An open API service indexing awesome lists of open source software.

https://github.com/zunyon/rls

rls is a file listing command-line tool with a different design philosophy from ls. rls highlights the unique part of each filename for easier fish shell filename completion.
https://github.com/zunyon/rls

c color columnar command-line filename-completion fish-shell ls openmp terminal

Last synced: 3 months ago
JSON representation

rls is a file listing command-line tool with a different design philosophy from ls. rls highlights the unique part of each filename for easier fish shell filename completion.

Awesome Lists containing this project

README

          

# rls

[English README](README_english.md) | [日本語 README](README.md)

[![CI](https://github.com/zunyon/rls/actions/workflows/makefile.yml/badge.svg)](https://github.com/zunyon/rls/actions/workflows/makefile.yml)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/zunyon/rls)

rls is a file listing command-line tool with a different design philosophy from ls.

rls highlights the unique part of each filename for easier fish shell filename completion.

## 概要
`rls`はファイルやディレクトリ名のユニークな部分文字列をハイライトして一覧表示するプログラムです。

`rls`の実行結果と,`fish` のファイル名補完機能を併用すると,キーボード入力を減らすことができます。

### ユニーク文字列のハイライト
`rls` は,`fish` がファイル名補完に必要な文字だけをハイライトしてファイル一覧を表示します。

`emacs n.c` のように,`n.c` の入力後に `TAB` を押すと,`fish` が `countfunction.c` と補完します。
![Unique filename completion demo](demo_rls.gif)

ハイライトされている部分を入力すれば,そのファイルが補完対象になります。

`rls.fish` の場合は,`.f` だけ入力すれば補完対象です。

### カスタマイズ可能な列表示
`rls` では,`-f` で表示項目と順序を完全に制御できます。

`rls -fmogcdwPN /init` と実行すると,mode owner group count date week PATH NAME の順番で表示します。
```shell
-rwxrwxrwx root root 2,735,264 Aug 7 04:54 Thu /init
```

`rls -fNtom /init` と実行すると,NAME time owner mode の順番で表示します。
```shell
init 2025, 08/07 04:54:55 root -rwxrwxrwx
```

また,`rls -fm,o,g,C,d,w,PN /init` と実行すると,csv 表記になります。

```shell
-rwxrwxrwx , root , root , 2735264 , Aug 7 04:54 , Thu , /init
```

その他の使用例:
```shell
rls -o -fcn -Fcc /usr/ # ディレクトリエントリ数順
rls -fCsn -Fss /tmp/ # ファイルサイズの大きい順
rls -fcNLE -Fee /mnt/ # エラーのあるファイルの確認(-f に c, s, d, w, m など lstat() を行う項目が必要)
rls -Fxss -fxsn ~/project/src # ファイルの種類(拡張子別),サイズ順
rls -fmogcdjNKLE -JxSRC=c,h -PSRC # ディレクトリにある拡張子が c,h のファイルだけ表示
find *.c -print | rls -- alr # find 結果に対して -alr
```
項目の種類については,ヘルプの `-f` を確認してください。

## 特徴的な他のオプション
- `-p` で,指定文字列のハイライト,`-f` で表示する全項目がハイライト対象
- `-F` で,ソート順を変更,`-f` で指定する全項目がソート対象,第 1,第 2,第 3,... のように複数のソート条件を指定可能
- `-nn` で,ユニーク文字列を指定文字で囲って表示,色付け不可な端末でのユニーク文字列表記
- `-e` で,elisp のような,拡張子だけが異なるファイル名が複数存在する "グループ" 向けユニーク文字列のハイライト



- `-J` で,`-fj` 向けファイルなどの分類分け,特定ファイルのラベル表示
- 異なる種類(拡張子)のファイルを同じグループに分類する(png, jpg, gif や、mov, avi, mp4 などを 1 つにまとめる)
- 例えば `xImage=png,jpg,gif:xMovie=mp4,mov,avi:xAudio=mp3,wav` と指定した場合
- `-f` の拡張子 `x` から `png` もしくは `jpg` もしくは `gif` が該当した場合,`Image`と表示する
- `-f` の拡張子 `x` から `mp4` もしくは `mov` もしくは `avi` が該当した場合,`Movie`と表示する
- `-f` の拡張子 `x` から `mp3` もしくは `wav` が該当した場合,`Audio`と表示する
- 1 ファイルだけを完全に特定したい場合は,`i, I` で inode番号を指定(`INo Delete=123456789` など)

## 開発環境・動作環境
`rls` のコンパイルに `make` を使用します。コンパイルに必要なファイルは `rls.c` のみです。

```sh
# clone repository
git clone https://github.com/zunyon/rls.git

cd rls
make
cp rls /usr/local/bin/

# option
cp rls.fish ~/.config/fish/completions/

# run
rls # Default details
rls -l # Default details (Long format)
```

make と rls の動作を確認した開発環境

`ubuntu-latest` と `macos-latest` は GitHub の環境です。
| |Ubuntu| wsl| Other|ubuntu-latest| macos-latest|
---:| ---:| ---:| ---:| ---:| ---:|
uname|6.15.0|6.6.87.2|6.12.25| 6.14.0|Darwin 24.6.0|
gcc|14.3.0| 11.4.0| 10.2.1| 13.30| 12.4.0|
make| 4.4.1| 4.3| 4.3| 4.3| 4.4.1|
fish| 4.0.2| 3.3.1| 3.1.2| -| -|

rls.c 以外のファイルについて

### `rls.c` 以外のファイルについて
rls.fish, countfunction.c, countfunction.h などが含まれています。

- countfunction.c, countfunction.h
- 標準的な関数への wrapper 関数

wrapper 関数はほぼ count しているだけなので,profile 時や,アルゴリズムの実装を試すときなどの指標になります。

また,opendir/readdir/closedir による scandir() の代替実装があるので,他の OS や開発環境などで参考になるかもしれません。

`make debug` や `make count` などで使用されます。
- rls.fish
- fish 用の .fish ファイル

~/.config/fish/completions/ に格納します。主要なオプションが記載されています。
- Makefile
- MD5 message digest

`make md5` を行うと `-f` で `5` が使用できるようになります。
- git

`make git` を行うと `-f` で `6` が使用できるようになります。
- showEscapeList.c
- Control Sequence Introducer 表示

元 `-256` オプションです。`cc showEscapeList.c` でコンパイルできます。

### 補完例の terminal 環境
上記の terminal 環境は下記です。
- `Windows Terminal` の配色を `Tango Dark` で使用
- 環境変数 `RLS_COLORS` に `base=37:normal=34:dir=36:fifo=33:socket=35:device=33:error=31:paint=32:normal=1:dir=1:socket=1:device=1:label=1:error=1:paint=1:reset=0` をセット

色の設定はデフォルトカラーと同じで,後半の `normal=1` 以降に強調(明るい色)を設定しています。

`rls` の色指定の実装は,256 色です。(5 で決め打ち,true color (2) の実装はしていません。`initColor()` 参照)

その中でも SGR(select Graphic Rendition)部分を指定しているので `Solarized Dark` 等の配色を使用すると,`Tango Dark` と異なる表示色になります。

## 動作原理
`rls` はユニーク文字列をハイライトして表示します。

ユニーク文字列の判断は,候補を選定したあとに 1 文字ずつ行う感じです。

- "候補" の選定
- 指定されたディレクトリの全ファイルを,"候補" に
- ファイル名と拡張子により,グループを判断し,"候補" に
- 全 "候補" を対象に
- ファイル名の 1 文字からパターンマッチング
- マッチング**しなかった文字列**を,ユニーク文字列と判断
- ハイライトして表示

ファイル名に複数のユニーク文字列候補がある場合,"文字数が少ない方","ファイル名の先頭に近い方" の候補が優先されます。

複数のユニーク文字列が含まれていた場合でも,ハイライトは 1 つだけです。

プログラムは,大まかに下記のようなステップに分かれています。
```mermaid
flowchart LR
subgraph Stage 1:前処理/データ取得
A["引数処理
(initAlist)"]
B["ファイル情報取得
(scandir/lstat)"]
end
A & B --> D

subgraph Stage 2:データ加工
D["項目書式設定
(dates, sizes, permissions)"]
E["ハイライト文字列
(uniqueCheck/MatchedString)"]
end
D --> E
E --> G

subgraph Stage 3:行/列処理
G["行操作
(rowSort/orderSort)"] --> H["列操作
(columns, padding)"]
end
H --> I & J & K

subgraph Stage 4:出力処理
I["ロング形式表示
(long format)"]
J["ショート形式表示
(short format)"]
K["JSON 形式表示
(JSON format)"]
L["色付け表示
(printUnique/printMatched)"]
end
I & J & K --> L
```

## rls に興味を持ってくれた方に

設計思想・作成背景

### 設計思想・作成背景
`rls` は,ファイル自体の情報に加えて,ディレクトリ内の他のファイル名との "差分" 情報を計算します。

ファイル一覧を表示するプログラムは多数存在しており,それらのプログラムは基本的にファイル自体の情報だけを扱います。

しかし,ファイル名を補完するには,ディレクトリ内にある他のファイル名との "差分" 情報が必要であり,ファイル自体の情報だけでは不十分です。

とくに,部分一致によるファイル名補完機能を提供する `shell` にとって,`rls` の示す "差分" 情報によってファイルを一意に特定することができます。

この "差分" 情報は,ファイルの増減・ファイル名の変更などによって変化する "可変" 情報であるため,ファイル名を補完する前に都度算出する必要があります。

これまで,この "差分" 情報を視覚化している既存のプログラムを見なかったため,`rls` ではハイライトして表示しています。
`rls` では,この "差分" 情報をユニーク文字列と呼んでいます。

### 固定情報と色の価値について
一般的に,ファイル情報に色を付けて表示するプログラムは多数存在していますが,主に "固定" 情報に対して "色" が用いられています。
固定情報を色で表す目的は "区別" や "注視" であることが多く,情報を "区別" するために属性自体に "色" を付けて表示したり,情報に "注視" させるために "場所 (位置)" に "色" が付けられています。

例えば,ファイルの属性 (mode や拡張子) による色分けや,固定された出力フォーマットとレイアウトの色分けです。

多くのファイル情報は,それ自体が変化しない "固定" 情報のため,ユーザーの慣れ (利用回数や利用時間により覚えていく) と共に "区別" や "注視" で用いられる "色" の価値は薄れていきます。(もちろん,必要に応じて固定情報を "区別" や "注視" したい場面も存在します。)



"色" は,画面に表示される元情報の情報量を変化(追加・変更・削除)させずに,新しく別の情報を付加できます。
そのため,変化を伴わない情報の "区別" や "注視" させる目的で "色" を使用するのは有用とは言えません。

`rls` では,ユーザーが頭の中で処理していた "可変" 情報のひとつを "色" で表示します。


知らないと奇妙なrlsの挙動について

### 知らないと奇妙なrlsの挙動について
`rls` を使用していると,その挙動に対して "??" と思うことがあるかもしれません。
そのような,`rls` の挙動とその判断基準を説明します。

- `rls` の `-c` オプションの設定エラーとリダイレクト

`-c` の設定エラーをリダイレクトする時の挙動についてです。

例えば,`rls -ck=31` は,実行時に設定エラーのメッセージが表示されますが,`rls -ck=31 > log` と実行しても `log` ファイルに設定エラーは記録されません。

`rls -ck=31 --color=always > log` のように `--color=always` を追加して実行すると,`log` ファイルに設定エラーが記録されます。



`rls` のデフォルト設定では,リダイレクト出力時にエスケープシーケンスを出力しないことが理由です。

リダイレクト時には,`-c` 機能自体(中のオプションの評価も)がスキップされるため,設定エラーが発生しません。
`-ck=31` がスキップされ,`rls` が実行されることになります。

`--color=always` を指定することにより,`-c` のオプションの評価が行われ,エラー内容がリダイレクトされるようになります。


- ユニーク文字列の判断で苦手なファイル名と,"グループ" 向けの `-e` オプション

`rls` がユニークな文字列を判断する際に,苦手なファイル名があります。

同じディレクトリに,拡張子だけが異なるファイルが複数存在する場合,`rls` は殆どユニーク文字列と判断しません。

例えば,elisp ファイル,画像・映像・オーディオファイルなど,別フォーマットのファイル存在している場合が該当します。

elisp ファイルを格納しているディレクトリなどは,`-e` を指定した方がユニーク文字列が表示されやすくなります。



`-e` オプションでは,これらの複数のファイルを同じ名前の "グループ" とし,ユニーク文字列を判断します。

その結果を "グループ" の 1 つのファイルのユニーク文字列をハイライトします。

1 回の補完機能では 2 つ以上のファイル名を補完することができないため,拡張子を除いたファイル名 "グループ" までがファイル名の補完対象になります。

"グループ" は paint 文字色で表示されます。


- `rls` のユニーク文字列の候補と,`fish` のファイル名の補完対象

あれ?,ユニーク文字列はこれじゃないの? と感じた時は,それがもっと良い条件のユニーク文字列かもしれません。

実際に,`rls` がハイライトしないユニーク文字列でも,`fish` が補完対象とする文字列はあります。

`-pxxx -r` などで,ユニークな文字列かどうか確認することができます。



これは,`rls` の色付け基準と `fish` のファイル補完基準が異なるために発生します。

例えば `fish` では,同じ文字が使用されている場合,ファイル名の先頭に使用されているファイルを優先して補完します。
Makefile と a.out の 2 つのファイルがある場合,`a` と入力して `TAB` を押した場合,`a.out` が優先して補完されます。

また,ファイル名・ディレクトリ名が同じ文字列を含む場合でも,コマンドが `cd` ならファイルは補完対象になりません。

これは,とても合理的ではありますが,`fish` に対して,あらかじめ `cd` に対する処理を設定していた結果であり,同じ `change directory` を行う別コマンドを実行しても,同じ効果は得られません。

`rls` ではファイル名からユニーク文字列を判断しているため,そもそも,`a` はユニーク文字列と判断されませんし,ユニーク文字列は使用するコマンドに依存しません。などです。


- エスケープ表記と文字の置換表示について

ファイル名の一部であっても,そのままでは `fish` の補完が効かないユニーク文字列があります。

例えば,` ` (半角空白) や `(` , `-`, `&` などのコマンドランで別の意味を持つ文字です。

`rls` では,上記の文字の前にエスケープ文字 `\` を表示します。
ファイル名を入力する際に,`\` から文字列を入力することで,補完が効くようになります。



また,`fish` のファイル名の補完機能では `-` と `_` が同等に扱われるため,`rls` では `-` と `_` を相互に置き換えて表示します。

`-` と `_` への置換は,動的に判断されます。

キー入力は,`1キーで完結 '-'` < `同時に2キー押す '_'` < `順番に2キー押す "\-"` の順番で手間がかかり,`-` と `_` を比べると `-` < `_` なのですが,`-` がユニーク文字列の先頭だった場合はエスケープ文字 `\` が必要になり `_` < `\-` となるので,`_` に置換した方が良いことになります。

置換表示の文字は paint 文字色で表示されます。
また,この置換表示は `-n` で無効化されます。


- `--` 指定時の `rls` の挙動

`rls` は `--` が指定された場合,ユニーク文字列の計算対象を変化させます。

`rls` は,指定されたディレクトリ内のファイル名の差分を計算しますが,`--` が指定された場合 stdin からの入力データのファイル名から差分を計算します。stdin が一つのディレクトリとして指定されるイメージです。

その結果,同じファイル名の場合でも,多くの場合,通常の `rls` の実行結果と異なるユニーク文字列が計算されます。



`-P` など,`fish` での処理を想定した機能を使用しないことから,`--` は `rls` の出力結果が `fish` 以外で処理されると想定されます。

よって `--` が指定された場合,`fish` 向け機能を停止し,下記のような動作を行います。

- "stdin からの入力データ" からユニーク文字列を計算する(該当したファイルのディレクトリごとのユニーク文字列の計算は行わない)
- `-` と `_` の相互変換,`\` によるエスケープを行わない

少しでも rls の実行時間を短くするには

### 少しでも rls の実行時間を短くするには
ファイルが多ければ,表示までの時間は長くなります。
当然ユニーク文字列も長くなります。

ファイルが多ければ取得する情報も増えますし,ユニーク文字列を判断するための比較回数も増えます。
これらのコードは特に時間がかかるので,そこを避けるようにします。
- `-s` で lstat() しなくなります。そうです。lstat() は遅い。
- `-n` でハイライトしなくなります。ユニーク文字列の判断も遅い。
- `-fn` でショート形式のレイアウト計算をしなくなります。レイアウト計算は遅い。

|コマンド |lstat()|ハイライト|レイアウト |備考 |
:--- |:--- |:--- |:--- |:--- |
`rls -l` |ON |ON |**ロング形式**|多くの情報が表示されます。出力は遅いです。|
`rls -s` |**OFF**|ON |ショート形式 |ハイライトされる一覧出力なら最速です。 |
`rls -sn` |**OFF**|**OFF** |ショート形式 |ショート形式表示の一覧出力なら最速です。 |
`rls -fn -n`|**OFF**|**OFF** |**ロング形式**|ファイル名の一覧が出力されるだけです。`rls` の表示の中で最速です。|

---

## ライセンス
[License: MIT](./LICENSE)

## ヘルプ
- [Version 0.5.0 current](./README_rls_current.md) のヘルプ
- [Version 0.4.0](./README_rls_v0.4.0.md) のヘルプ
- [Version 0.3.0](./README_rls_v0.3.0.md) のヘルプ


## v0.4.0 からの変更内容
- fix `makeMode()` の setuid, setgid, sticky bit の対応修正