add colors/icons file support

cc #505
This commit is contained in:
Gokcehan 2022-02-13 16:58:53 +03:00
parent 375133e483
commit 17453f10f5
8 changed files with 210 additions and 14 deletions

View File

@ -72,6 +72,12 @@ func parseStyles() styleMap {
sm.parseGNU(env)
}
for _, path := range gColorsPaths {
if _, err := os.Stat(path); !os.IsNotExist(err) {
sm.parseFile(path)
}
}
return sm
}
@ -158,6 +164,35 @@ func applyAnsiCodes(s string, st tcell.Style) tcell.Style {
return st
}
func (sm styleMap) parseFile(path string) {
log.Printf("reading file: %s", path)
f, err := os.Open(path)
if err != nil {
log.Printf("opening colors file: %s", err)
return
}
defer f.Close()
pairs, err := readPairs(f)
if err != nil {
log.Printf("reading colors file: %s", err)
return
}
for _, pair := range pairs {
key, val := pair[0], pair[1]
key = replaceTilde(key)
if filepath.IsAbs(key) {
key = filepath.Clean(key)
}
sm[key] = applyAnsiCodes(val, tcell.StyleDefault)
}
}
// This function parses $LS_COLORS environment variable.
func (sm styleMap) parseGNU(env string) {
for _, entry := range strings.Split(env, ":") {

20
doc.go
View File

@ -194,6 +194,16 @@ Configuration files should be located at:
unix /etc/lf/lfrc ~/.config/lf/lfrc
windows C:\ProgramData\lf\lfrc C:\Users\<user>\AppData\Local\lf\lfrc
Colors file should be located at:
unix ~/.local/share/lf/colors
windows C:\Users\<user>\AppData\Local\lf\colors
Icons file should be located at:
unix ~/.local/share/lf/icons
windows C:\Users\<user>\AppData\Local\lf\icons
Selection file should be located at:
unix ~/.local/share/lf/files
@ -1297,17 +1307,20 @@ Colors are set in the following order:
2. LSCOLORS (Mac/BSD ls)
3. LS_COLORS (GNU ls)
4. LF_COLORS (lf specific)
5. colors file (lf specific)
Please refer to the corresponding man pages for more information about 'LSCOLORS' and 'LS_COLORS'.
'LF_COLORS' is provided with the same syntax as 'LS_COLORS' in case you want to configure colors only for lf but not ls.
This can be useful since there are some differences between ls and lf, though one should expect the same behavior for common cases.
Colors file is provided for easier configuration without environment variables.
This file should consist of whitespace separated pairs with '#' character to start comments until the end of line.
You can configure lf colors in two different ways.
First, you can only configure 8 basic colors used by your terminal and lf should pick up those colors automatically.
Depending on your terminal, you should be able to select your colors from a 24-bit palette.
This is the recommended approach as colors used by other programs will also match each other.
Second, you can set the values of environmental variables mentioned above for fine grained customization.
Second, you can set the values of environment variables mentioned above for fine grained customization.
Note that 'LS_COLORS/LF_COLORS' are more powerful than 'LSCOLORS' and they can be used even when GNU programs are not installed on the system.
You can combine this second method with the first method for best results.
@ -1409,9 +1422,10 @@ https://en.wikipedia.org/wiki/ANSI_escape_code.
Icons
Icons are configured using 'LF_ICONS' environment variable.
This variable uses the same syntax as 'LS_COLORS/LF_COLORS'.
Icons are configured using 'LF_ICONS' environment variable or an icons file.
The variable uses the same syntax as 'LS_COLORS/LF_COLORS'.
Instead of colors, you should put a single characters as values of entries.
Icons file should consist of whitespace separated pairs with '#' character to start comments until the end of line.
Do not forget to enable 'icons' option to see the icons.
Default values are as follows given with their matching order in lf:

View File

@ -199,6 +199,16 @@ Configuration files should be located at:
unix /etc/lf/lfrc ~/.config/lf/lfrc
windows C:\ProgramData\lf\lfrc C:\Users\<user>\AppData\Local\lf\lfrc
Colors file should be located at:
unix ~/.local/share/lf/colors
windows C:\Users\<user>\AppData\Local\lf\colors
Icons file should be located at:
unix ~/.local/share/lf/icons
windows C:\Users\<user>\AppData\Local\lf\icons
Selection file should be located at:
unix ~/.local/share/lf/files
@ -1457,12 +1467,16 @@ are set in the following order:
2. LSCOLORS (Mac/BSD ls)
3. LS_COLORS (GNU ls)
4. LF_COLORS (lf specific)
5. colors file (lf specific)
Please refer to the corresponding man pages for more information about
'LSCOLORS' and 'LS_COLORS'. 'LF_COLORS' is provided with the same syntax as
'LS_COLORS' in case you want to configure colors only for lf but not ls.
This can be useful since there are some differences between ls and lf,
though one should expect the same behavior for common cases.
though one should expect the same behavior for common cases. Colors file is
provided for easier configuration without environment variables. This file
should consist of whitespace separated pairs with '#' character to start
comments until the end of line.
You can configure lf colors in two different ways. First, you can only
configure 8 basic colors used by your terminal and lf should pick up those
@ -1470,8 +1484,8 @@ colors automatically. Depending on your terminal, you should be able to
select your colors from a 24-bit palette. This is the recommended approach
as colors used by other programs will also match each other.
Second, you can set the values of environmental variables mentioned above
for fine grained customization. Note that 'LS_COLORS/LF_COLORS' are more
Second, you can set the values of environment variables mentioned above for
fine grained customization. Note that 'LS_COLORS/LF_COLORS' are more
powerful than 'LSCOLORS' and they can be used even when GNU programs are not
installed on the system. You can combine this second method with the first
method for best results.
@ -1589,11 +1603,13 @@ https://en.wikipedia.org/wiki/ANSI_escape_code.
Icons
Icons are configured using 'LF_ICONS' environment variable. This variable
uses the same syntax as 'LS_COLORS/LF_COLORS'. Instead of colors, you should
put a single characters as values of entries. Do not forget to enable
'icons' option to see the icons. Default values are as follows given with
their matching order in lf:
Icons are configured using 'LF_ICONS' environment variable or an icons file.
The variable uses the same syntax as 'LS_COLORS/LF_COLORS'. Instead of
colors, you should put a single characters as values of entries. Icons file
should consist of whitespace separated pairs with '#' character to start
comments until the end of line. Do not forget to enable 'icons' option to
see the icons. Default values are as follows given with their matching order
in lf:
ln 🗎
or 🗎

View File

@ -35,9 +35,44 @@ func parseIcons() iconMap {
im.parseEnv(env)
}
for _, path := range gIconsPaths {
if _, err := os.Stat(path); !os.IsNotExist(err) {
im.parseFile(path)
}
}
return im
}
func (im iconMap) parseFile(path string) {
log.Printf("reading file: %s", path)
f, err := os.Open(path)
if err != nil {
log.Printf("opening icons file: %s", err)
return
}
defer f.Close()
pairs, err := readPairs(f)
if err != nil {
log.Printf("reading icons file: %s", err)
return
}
for _, pair := range pairs {
key, val := pair[0], pair[1]
key = replaceTilde(key)
if filepath.IsAbs(key) {
key = filepath.Clean(key)
}
im[key] = val
}
}
func (im iconMap) parseEnv(env string) {
for _, entry := range strings.Split(env, ":") {
if entry == "" {

21
lf.1
View File

@ -221,6 +221,20 @@ Configuration files should be located at:
windows C:\eProgramData\elf\elfrc C:\eUsers\e<user>\eAppData\eLocal\elf\elfrc
.EE
.PP
Colors file should be located at:
.PP
.EX
unix ~/.local/share/lf/colors
windows C:\eUsers\e<user>\eAppData\eLocal\elf\ecolors
.EE
.PP
Icons file should be located at:
.PP
.EX
unix ~/.local/share/lf/icons
windows C:\eUsers\e<user>\eAppData\eLocal\elf\eicons
.EE
.PP
Selection file should be located at:
.PP
.EX
@ -1450,13 +1464,14 @@ lf tries to automatically adapt its colors to the environment. It starts with a
2. LSCOLORS (Mac/BSD ls)
3. LS_COLORS (GNU ls)
4. LF_COLORS (lf specific)
5. colors file (lf specific)
.EE
.PP
Please refer to the corresponding man pages for more information about 'LSCOLORS' and 'LS_COLORS'. 'LF_COLORS' is provided with the same syntax as 'LS_COLORS' in case you want to configure colors only for lf but not ls. This can be useful since there are some differences between ls and lf, though one should expect the same behavior for common cases.
Please refer to the corresponding man pages for more information about 'LSCOLORS' and 'LS_COLORS'. 'LF_COLORS' is provided with the same syntax as 'LS_COLORS' in case you want to configure colors only for lf but not ls. This can be useful since there are some differences between ls and lf, though one should expect the same behavior for common cases. Colors file is provided for easier configuration without environment variables. This file should consist of whitespace separated pairs with '#' character to start comments until the end of line.
.PP
You can configure lf colors in two different ways. First, you can only configure 8 basic colors used by your terminal and lf should pick up those colors automatically. Depending on your terminal, you should be able to select your colors from a 24-bit palette. This is the recommended approach as colors used by other programs will also match each other.
.PP
Second, you can set the values of environmental variables mentioned above for fine grained customization. Note that 'LS_COLORS/LF_COLORS' are more powerful than 'LSCOLORS' and they can be used even when GNU programs are not installed on the system. You can combine this second method with the first method for best results.
Second, you can set the values of environment variables mentioned above for fine grained customization. Note that 'LS_COLORS/LF_COLORS' are more powerful than 'LSCOLORS' and they can be used even when GNU programs are not installed on the system. You can combine this second method with the first method for best results.
.PP
Lastly, you may also want to configure the colors of the prompt line to match the rest of the colors. Colors of the prompt line can be configured using the 'promptfmt' option which can include hardcoded colors as ansi escapes. See the default value of this option to have an idea about how to color this line.
.PP
@ -1557,7 +1572,7 @@ Having such a long variable definition in a shell configuration file might be un
.PP
See the wiki page for ansi escape codes https://en.wikipedia.org/wiki/ANSI_escape_code.
.SH ICONS
Icons are configured using 'LF_ICONS' environment variable. This variable uses the same syntax as 'LS_COLORS/LF_COLORS'. Instead of colors, you should put a single characters as values of entries. Do not forget to enable 'icons' option to see the icons. Default values are as follows given with their matching order in lf:
Icons are configured using 'LF_ICONS' environment variable or an icons file. The variable uses the same syntax as 'LS_COLORS/LF_COLORS'. Instead of colors, you should put a single characters as values of entries. Icons file should consist of whitespace separated pairs with '#' character to start comments until the end of line. Do not forget to enable 'icons' option to see the icons. Default values are as follows given with their matching order in lf:
.PP
.EX
ln 🗎

57
misc.go
View File

@ -1,7 +1,10 @@
package main
import (
"bufio"
"errors"
"fmt"
"io"
"path/filepath"
"regexp"
"strconv"
@ -133,6 +136,60 @@ func splitWord(s string) (word, rest string) {
return
}
var reComment = regexp.MustCompile(`#.*$`)
var reTrailingSpace = regexp.MustCompile(`\s+$`)
func readPairs(r io.Reader) ([][]string, error) {
var pairs [][]string
s := bufio.NewScanner(r)
for s.Scan() {
line := s.Text()
line = reComment.ReplaceAllString(line, "")
line = reTrailingSpace.ReplaceAllString(line, "")
if line == "" {
continue
}
squote, dquote := false, false
pair := strings.FieldsFunc(line, func(r rune) bool {
if r == '\'' && !dquote {
squote = !squote
} else if r == '"' && !squote {
dquote = !dquote
}
return !squote && !dquote && unicode.IsSpace(r)
})
if len(pair) != 2 {
return nil, errors.New(fmt.Sprintf("expected pair but found: %s", s.Text()))
continue
}
for i := 0; i < len(pair); i++ {
squote, dquote := false, false
buf := make([]rune, 0, len(pair[i]))
for _, r := range pair[i] {
if r == '\'' && !dquote {
squote = !squote
continue
}
if r == '"' && !squote {
dquote = !dquote
continue
}
buf = append(buf, r)
}
pair[i] = string(buf)
}
pairs = append(pairs, pair)
}
return pairs, nil
}
// This function converts a size in bytes to a human readable form using metric
// suffixes (e.g. 1K = 1000). For values less than 10 the first significant
// digit is shown, otherwise it is hidden. Numbers are always rounded down.

12
os.go
View File

@ -31,6 +31,8 @@ var (
var (
gUser *user.User
gConfigPaths []string
gColorsPaths []string
gIconsPaths []string
gFilesPath string
gMarksPath string
gHistoryPath string
@ -79,6 +81,16 @@ func init() {
filepath.Join(config, "lf", "lfrc"),
}
gColorsPaths = []string{
filepath.Join("/etc", "lf", "colors"),
filepath.Join(config, "lf", "colors"),
}
gIconsPaths = []string{
filepath.Join("/etc", "lf", "icons"),
filepath.Join(config, "lf", "icons"),
}
data := os.Getenv("XDG_DATA_HOME")
if data == "" {
data = filepath.Join(gUser.HomeDir, ".local", "share")

View File

@ -30,6 +30,8 @@ var (
var (
gUser *user.User
gConfigPaths []string
gColorsPaths []string
gIconsPaths []string
gFilesPath string
gMarksPath string
gHistoryPath string
@ -68,6 +70,16 @@ func init() {
filepath.Join(data, "lf", "lfrc"),
}
gColorsPaths = []string{
filepath.Join(os.Getenv("ProgramData"), "lf", "colors"),
filepath.Join(data, "lf", "colors"),
}
gIconsPaths = []string{
filepath.Join(os.Getenv("ProgramData"), "lf", "icons"),
filepath.Join(data, "lf", "icons"),
}
gFilesPath = filepath.Join(data, "lf", "files")
gMarksPath = filepath.Join(data, "lf", "marks")
gHistoryPath = filepath.Join(data, "lf", "history")