mirror of https://github.com/Hilbis/Hilbish
Compare commits
7 Commits
8b5dc69950
...
eb0a81f7a2
Author | SHA1 | Date |
---|---|---|
TorchedSammy | eb0a81f7a2 | |
TorchedSammy | 24b88a0483 | |
TorchedSammy | f73c6d4aa8 | |
TorchedSammy | 925ded6cea | |
TorchedSammy | 92d0e195ab | |
TorchedSammy | 4da82e872c | |
TorchedSammy | b0ece71de3 |
17
CHANGELOG.md
17
CHANGELOG.md
|
@ -1,5 +1,21 @@
|
||||||
# 🎀 Changelog
|
# 🎀 Changelog
|
||||||
|
|
||||||
|
## [1.1.0] - 2021-03-17
|
||||||
|
### Added
|
||||||
|
- `hilbish.vimAction` hook (`doc vimMode actions`)
|
||||||
|
- `command.not-executable` hook (will replace `command.no-perm` in a future release)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Check if interactive before adding to history
|
||||||
|
- Escape in vim mode exits all modes and not only insert
|
||||||
|
- Make 2nd line in prompt empty if entire prompt is 1 line
|
||||||
|
- Completion menu doesnt appear if there is only 1 result
|
||||||
|
- Ignore SIGQUIT, which caused a panic unhandled
|
||||||
|
- Remove hostname in greeting on Windows
|
||||||
|
- Handle PATH binaries properly on Windows
|
||||||
|
- Fix removal of dot in the beginning of folders/files that have them for file complete
|
||||||
|
- Fix prompt being set to the continue prompt even when exited
|
||||||
|
|
||||||
## [1.0.4] - 2021-03-12
|
## [1.0.4] - 2021-03-12
|
||||||
### Fixed
|
### Fixed
|
||||||
- Panic when history directory doesn't exist
|
- Panic when history directory doesn't exist
|
||||||
|
@ -392,6 +408,7 @@ This input for example will prompt for more input to complete:
|
||||||
|
|
||||||
First "stable" release of Hilbish.
|
First "stable" release of Hilbish.
|
||||||
|
|
||||||
|
[1.1.0]: https://github.com/Rosettea/Hilbish/compare/v1.0.4...v1.1.0
|
||||||
[1.0.4]: https://github.com/Rosettea/Hilbish/compare/v1.0.3...v1.0.4
|
[1.0.4]: https://github.com/Rosettea/Hilbish/compare/v1.0.3...v1.0.4
|
||||||
[1.0.3]: https://github.com/Rosettea/Hilbish/compare/v1.0.2...v1.0.3
|
[1.0.3]: https://github.com/Rosettea/Hilbish/compare/v1.0.2...v1.0.3
|
||||||
[1.0.2]: https://github.com/Rosettea/Hilbish/compare/v1.0.1...v1.0.2
|
[1.0.2]: https://github.com/Rosettea/Hilbish/compare/v1.0.1...v1.0.2
|
||||||
|
|
|
@ -33,7 +33,7 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) {
|
||||||
if len(fileCompletions) != 0 {
|
if len(fileCompletions) != 0 {
|
||||||
for _, f := range fileCompletions {
|
for _, f := range fileCompletions {
|
||||||
name := strings.Replace(query + f, "~", curuser.HomeDir, 1)
|
name := strings.Replace(query + f, "~", curuser.HomeDir, 1)
|
||||||
if info, err := os.Stat(name); err == nil && info.Mode().Perm() & 0100 == 0 {
|
if err := findExecutable(name, false, true); err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
completions = append(completions, f)
|
completions = append(completions, f)
|
||||||
|
@ -51,7 +51,8 @@ func binaryComplete(query, ctx string, fields []string) ([]string, string) {
|
||||||
// get basename from matches
|
// get basename from matches
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
// check if we have execute permissions for our match
|
// check if we have execute permissions for our match
|
||||||
if info, err := os.Stat(match); err == nil && info.Mode().Perm() & 0100 == 0 {
|
err := findExecutable(match, true, false)
|
||||||
|
if err != nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// get basename from match
|
// get basename from match
|
||||||
|
@ -93,7 +94,7 @@ func matchPath(path, pref string) ([]string, error) {
|
||||||
for _, match := range matches {
|
for _, match := range matches {
|
||||||
name := filepath.Base(match)
|
name := filepath.Base(match)
|
||||||
p := filepath.Base(pref)
|
p := filepath.Base(pref)
|
||||||
if pref == "" {
|
if pref == "" || pref == "./" {
|
||||||
p = ""
|
p = ""
|
||||||
}
|
}
|
||||||
name = strings.TrimPrefix(name, p)
|
name = strings.TrimPrefix(name, p)
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
Vim actions are essentially just when a user uses a Vim keybind.
|
||||||
|
Things like yanking and pasting are Vim actions.
|
||||||
|
This is not an "offical Vim thing," just a Hilbish thing.
|
||||||
|
|
||||||
|
The `hilbish.vimAction` hook is thrown whenever a Vim action occurs.
|
||||||
|
It passes 2 arguments: the action name, and an array (table) of args
|
||||||
|
relating to it.
|
||||||
|
|
||||||
|
Here is documentation for what the table of args will hold for an
|
||||||
|
appropriate Vim action.
|
||||||
|
|
||||||
|
- `yank`: register, yankedText
|
||||||
|
The first argument for the yank action is the register yankedText goes to.
|
||||||
|
|
||||||
|
- `paste`: register, pastedText
|
||||||
|
The first argument for the paste action is the register pastedText is taken from.
|
|
@ -0,0 +1,4 @@
|
||||||
|
Hilbish has a Vim binding input mode accessible for use.
|
||||||
|
It can be enabled with the `hilbish.inputMode` function (check `doc hilbish`).
|
||||||
|
|
||||||
|
This is documentation for everything relating to it.
|
12
exec.go
12
exec.go
|
@ -6,6 +6,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -161,15 +162,20 @@ func execCommand(cmd, old string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func lookpath(file string) error { // custom lookpath function so we know if a command is found *and* is executable
|
func lookpath(file string) error { // custom lookpath function so we know if a command is found *and* is executable
|
||||||
skip := []string{"./", "/", "../", "~/"}
|
var skip []string
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
skip = []string{"./", "../", "~/", "C:"}
|
||||||
|
} else {
|
||||||
|
skip = []string{"./", "/", "../", "~/"}
|
||||||
|
}
|
||||||
for _, s := range skip {
|
for _, s := range skip {
|
||||||
if strings.HasPrefix(file, s) {
|
if strings.HasPrefix(file, s) {
|
||||||
return findExecutable(file)
|
return findExecutable(file, false, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
|
for _, dir := range filepath.SplitList(os.Getenv("PATH")) {
|
||||||
path := filepath.Join(dir, file)
|
path := filepath.Join(dir, file)
|
||||||
err := findExecutable(path)
|
err := findExecutable(path, true, false)
|
||||||
if err == errNotExec {
|
if err == errNotExec {
|
||||||
return err
|
return err
|
||||||
} else if err == nil {
|
} else if err == nil {
|
||||||
|
|
|
@ -6,13 +6,19 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func findExecutable(path string) error {
|
func findExecutable(path string, inPath, dirs bool) error {
|
||||||
f, err := os.Stat(path)
|
f, err := os.Stat(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if dirs {
|
||||||
|
if m := f.Mode(); m & 0111 != 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if m := f.Mode(); !m.IsDir() && m & 0111 != 0 {
|
if m := f.Mode(); !m.IsDir() && m & 0111 != 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return errNotExec
|
return errNotExec
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,21 +7,31 @@ import (
|
||||||
"os"
|
"os"
|
||||||
)
|
)
|
||||||
|
|
||||||
func findExecutable(path string) error {
|
func findExecutable(path string, inPath, dirs bool) error {
|
||||||
nameExt := filepath.Ext(path)
|
nameExt := filepath.Ext(path)
|
||||||
|
pathExts := filepath.SplitList(os.Getenv("PATHEXT"))
|
||||||
|
if inPath {
|
||||||
if nameExt == "" {
|
if nameExt == "" {
|
||||||
for _, ext := range filepath.SplitList(os.Getenv("PATHEXT")) {
|
for _, ext := range pathExts {
|
||||||
_, err := os.Stat(path + ext)
|
_, err := os.Stat(path + ext)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
|
|
||||||
_, err := os.Stat(path)
|
_, err := os.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
if contains(pathExts, nameExt) { return nil }
|
||||||
return errNotExec
|
return errNotExec
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
if contains(pathExts, nameExt) { return nil }
|
||||||
|
return errNotExec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return os.ErrNotExist
|
return os.ErrNotExist
|
||||||
}
|
}
|
||||||
|
|
11
main.go
11
main.go
|
@ -198,6 +198,8 @@ input:
|
||||||
for {
|
for {
|
||||||
input, err = continuePrompt(input)
|
input, err = continuePrompt(input)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
running = true
|
||||||
|
lr.SetPrompt(fmtPrompt(prompt))
|
||||||
goto input // continue inside nested loop
|
goto input // continue inside nested loop
|
||||||
}
|
}
|
||||||
if !strings.HasSuffix(input, "\\") {
|
if !strings.HasSuffix(input, "\\") {
|
||||||
|
@ -284,3 +286,12 @@ func removeDupes(slice []string) []string {
|
||||||
|
|
||||||
return newSlice
|
return newSlice
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func contains(s []string, e string) bool {
|
||||||
|
for _, a := range s {
|
||||||
|
if a == e {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ bait.catch('command.not-found', function(cmd)
|
||||||
print(string.format('hilbish: %s not found', cmd))
|
print(string.format('hilbish: %s not found', cmd))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
bait.catch('command.no-perm', function(cmd)
|
bait.catch('command.not-executable', function(cmd)
|
||||||
print(string.format('hilbish: %s: no permission', cmd))
|
print(string.format('hilbish: %s: not executable', cmd))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
|
@ -96,9 +96,6 @@ func (rl *Instance) getTabSearchCompletion() {
|
||||||
// Set the hint for this completion mode
|
// Set the hint for this completion mode
|
||||||
rl.hintText = append([]rune("Completion search: "), rl.tfLine...)
|
rl.hintText = append([]rune("Completion search: "), rl.tfLine...)
|
||||||
|
|
||||||
// Set the hint for this completion mode
|
|
||||||
rl.hintText = append([]rune("Completion search: "), rl.tfLine...)
|
|
||||||
|
|
||||||
for _, g := range rl.tcGroups {
|
for _, g := range rl.tcGroups {
|
||||||
g.updateTabFind(rl)
|
g.updateTabFind(rl)
|
||||||
}
|
}
|
||||||
|
|
2
vars.go
2
vars.go
|
@ -2,7 +2,7 @@ package main
|
||||||
|
|
||||||
// String vars that are free to be changed at compile time
|
// String vars that are free to be changed at compile time
|
||||||
var (
|
var (
|
||||||
version = "v1.0.4"
|
version = "v1.1.0"
|
||||||
defaultConfDir = "" // ~ will be substituted for home, path for user's default config
|
defaultConfDir = "" // ~ will be substituted for home, path for user's default config
|
||||||
defaultHistDir = ""
|
defaultHistDir = ""
|
||||||
commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'"
|
commonRequirePaths = "';./libs/?/init.lua;./?/init.lua;./?/?.lua'"
|
||||||
|
|
Loading…
Reference in New Issue