Skip to content
This repository was archived by the owner on Jan 10, 2026. It is now read-only.

Commit ea0bad5

Browse files
feat: 🎸 add emoji title for styling (#12)
* elixir binary-size for string * feat: 🎸 add emoji title for styling * chore: 🤖 0.2.1
1 parent 40588d8 commit ea0bad5

File tree

5 files changed

+79
-74
lines changed

5 files changed

+79
-74
lines changed

README.md

Lines changed: 48 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
# CHR
22

3-
The commands history report CLI for the Elixir developers.
3+
CHR(Command History Report): A command history report tool base on your shell history file.
44

5+
> Your data is yours.
6+
7+
[![Hex.pm version](https://img.shields.io/hexpm/v/chr.svg)](https://hex.pm/packages/chr)
58
[![Twitter: ThaddeusJiang](https://img.shields.io/twitter/follow/ThaddeusJiang.svg?style=social)](https://twitter.com/ThaddeusJiang)
69

7-
> The name "chr" is derived from "commands history report".
810
> Inspired by the Fig report, this tool aims to provide a similar experience for those not using Fig.
911
1012
![Fig 2022 Wrapped](https://pbs.twimg.com/media/FkqSV8hXoAEXqON?format=png&name=small)
@@ -49,70 +51,70 @@ chr
4951
│ source code: https://github.com/ThaddeusJiang/chr │
5052
│ │
5153
└─────────────────────────────────────────────────────────────┘
52-
┌─Top Commands────┐
53-
│ │
54-
496 git │
55-
200 cd │
56-
110 code │
57-
75 ls
58-
48 clear
59-
48 mix
60-
46 docker │
61-
32 ./chr
62-
30 npm
63-
27 erl
64-
│ │
65-
└─────────────────┘
66-
┌─Top Directories─────────────┐
54+
┌─🏆 Top Commands────┐
55+
56+
810 git
57+
276 cd
58+
183 code
59+
150 mix
60+
111 ls
61+
93 clear
62+
63 docker
63+
59 npm
64+
49 k6
65+
45 ./gitlab_cli
66+
67+
└────────────────────
68+
┌─📂 Top Directories──────────┐
6769
│ │
68-
│ 24 git/work/plugo │
70+
│ 36 git/work/plugo │
71+
│ 24 repos/backend │
6972
│ 16 repos/roaming-gateway │
70-
│ 15 repos/backend │
71-
│ 11 repos/k8s │
72-
│ 10 git/ThaddeusJiang │
73+
│ 14 git/ThaddeusJiang │
74+
│ 13 repos/k8s │
7375
│ │
7476
└─────────────────────────────┘
75-
┌─Busiest Day──────────────────┐
77+
┌─💦 Busiest Day───────────────┐
7678
│ │
77-
274 commands on 2024-02-08
79+
372 commands on 2024-02-19
7880
│ │
7981
└──────────────────────────────┘
80-
┌─Weekly Activity────────────┐
82+
┌─📅 Weekly Activity─────────┐
8183
│ │
8284
│ Mon │
83-
│ Tue ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
84-
│ Wed ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
85-
│ Thu ▓▓▓▓▓▓▓▓▓
86-
│ Fri ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
87-
│ Sat ▓▓▓▓▓▓▓▓▓▓
88-
│ Sun
85+
│ Tue ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
86+
│ Wed ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
87+
│ Thu ▓▓▓▓▓▓▓
88+
│ Fri ▓▓▓▓▓▓▓▓▓▓▓
89+
│ Sat ▓▓▓▓▓▓▓▓▓▓
90+
│ Sun
8991
│ │
9092
└────────────────────────────┘
91-
┌─Daily Activity────────────┐
93+
┌─🕑 Daily Activity─────────┐
9294
│ │
9395
│ 01 │
9496
│ 02 │
9597
│ 03 │
9698
│ 04 │
97-
│ 05
98-
│ 06
99-
│ 07
99+
│ 05
100+
│ 06 ▓▓
101+
│ 07
100102
│ 08 │
101103
│ 09 │
102104
│ 10 ▓ │
103-
│ 11 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
104-
│ 12 ▓▓▓▓▓▓▓▓
105-
│ 13 ▓▓▓▓▓▓▓▓▓▓▓
106-
│ 14 ▓▓▓▓▓▓▓
107-
│ 15 ▓▓▓▓▓▓▓▓▓▓▓▓▓
108-
│ 16 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
109-
│ 17 ▓▓▓▓▓▓▓▓
110-
│ 18 ▓▓▓▓▓▓▓▓
111-
│ 19 ▓▓▓▓▓▓▓
112-
│ 20 ▓▓▓▓▓
105+
│ 11 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
106+
│ 12 ▓▓▓▓▓▓▓▓▓▓
107+
│ 13 ▓▓▓▓▓▓▓▓▓▓▓
108+
│ 14 ▓▓▓▓▓▓▓▓▓
109+
│ 15 ▓▓▓▓▓▓▓▓▓▓▓▓▓
110+
│ 16 ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
111+
│ 17 ▓▓▓▓▓▓▓▓▓▓
112+
│ 18 ▓▓▓▓▓▓▓▓▓▓▓▓
113+
│ 19 ▓▓▓▓▓▓▓
114+
│ 20 ▓▓▓▓▓▓▓▓▓▓▓
113115
│ 21 ▓▓▓▓▓▓▓ │
114-
│ 22 ▓▓▓▓▓▓
115-
│ 23 ▓▓▓▓
116+
│ 22 ▓▓▓▓▓▓
117+
│ 23 ▓▓▓▓
116118
│ 24 ▓ │
117119
│ │
118120
└───────────────────────────┘

lib/chr.ex

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,36 @@ defmodule Chr do
1818

1919
{:error, _} ->
2020
[]
21-
22-
_ ->
23-
[]
2421
end
2522
end
2623

2724
@doc """
2825
pick up command from history record
26+
27+
## Examples
28+
29+
iex> Chr.pick_up_command(": 1707397937:0;cat ~/.zsh_history")
30+
"cat"
31+
32+
iex> Chr.pick_up_command(": 1707397937:0;clear")
33+
"clear"
2934
"""
3035
def pick_up_command(string) do
3136
string
32-
|> String.split(" ")
37+
|> String.split(";")
3338
|> List.delete_at(0)
3439
|> List.first()
35-
|> String.split(";")
36-
|> List.last()
40+
|> String.split(" ")
41+
|> List.first()
3742
end
3843

3944
@doc """
4045
pick up directory from history record
46+
47+
## Examples
48+
49+
iex> Chr.pick_up_directory(": 1707397937:0;cd ~/projects/chr")
50+
"~/projects/chr"
4151
"""
4252
def pick_up_directory(string) do
4353
[head | tail] =
@@ -91,7 +101,7 @@ defmodule Chr do
91101
history_list
92102
|> Enum.map(&pick_up_directory/1)
93103
|> Enum.reject(&is_nil/1)
94-
|> Enum.reject(&(String.length(&1) < 2 || String.ends_with?(&1, "..")))
104+
|> Enum.reject(&(String.length(&1) < 2 || String.ends_with?(&1, ".")))
95105
|> Enum.reduce(%{}, fn directory, acc ->
96106
Map.update(acc, directory, 1, &(&1 + 1))
97107
end)
@@ -117,12 +127,9 @@ defmodule Chr do
117127
~U[2024-02-08 22:12:17Z]
118128
"""
119129
def pick_up_local_datetime(string) do
120-
string
121-
|> String.split(":")
122-
|> List.delete_at(0)
123-
|> List.first()
124-
|> String.split(" ")
125-
|> List.last()
130+
<<_::binary-size(2), timestamp::binary-size(10), _::binary>> = string
131+
132+
timestamp
126133
|> String.to_integer()
127134
|> DateTime.from_unix!()
128135
|> DateTime.add(Chr.timezone_offset(), :hour)

lib/chr/print.ex

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ defmodule Chr.Print do
9191
count_stringify(5, count |> Integer.to_string(), command)
9292
end)
9393
|> Enum.join("\n")
94-
# FIXME: Owl's bug: right border malposition when title has emoji
95-
# |> print_count_number("🏆 Top Commands", :red)
96-
|> print_count_number("Top Commands", :red)
94+
|> print_count_number("🏆 Top Commands", :red)
9795
end
9896

9997
@doc """
@@ -106,8 +104,7 @@ defmodule Chr.Print do
106104
count_stringify(5, count |> Integer.to_string(), directory)
107105
end)
108106
|> Enum.join("\n")
109-
# |> print_count_number("📂 Top Directories", :red, 5)
110-
|> print_count_number("Top Directories", :red)
107+
|> print_count_number("📂 Top Directories", :red, 5)
111108
end
112109

113110
defp busiest_day_stringify({day, count}) do
@@ -121,8 +118,7 @@ defmodule Chr.Print do
121118
histories
122119
|> Chr.busiest_day()
123120
|> busiest_day_stringify()
124-
# |> print_count_number("💦 Busiest Day", :green)
125-
|> print_count_number("Busiest Day", :green)
121+
|> print_count_number("💦 Busiest Day", :green)
126122
end
127123

128124
@doc """
@@ -135,8 +131,7 @@ defmodule Chr.Print do
135131
percent_stringify(day, count)
136132
end)
137133
|> Enum.join("\n")
138-
# |> print_count_bar("📅 Weekly Activity", :yellow)
139-
|> print_count_bar("Weekly Activity", :yellow)
134+
|> print_count_bar("📅 Weekly Activity", :yellow)
140135
end
141136

142137
@doc """
@@ -149,8 +144,7 @@ defmodule Chr.Print do
149144
percent_stringify(hour, count)
150145
end)
151146
|> Enum.join("\n")
152-
# |> print_count_bar("🕑 Daily Activity", :magenta)
153-
|> print_count_bar("Daily Activity", :magenta)
147+
|> print_count_bar("🕑 Daily Activity", :magenta)
154148
end
155149

156150
@doc """

mix.exs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ defmodule Chr.MixProject do
44
def project do
55
[
66
app: :chr,
7-
version: "0.2.0",
7+
version: "0.2.1",
88
elixir: "~> 1.15",
99
build_embedded: Mix.env() == :prod,
1010
start_permanent: Mix.env() == :prod,
1111
description: description(),
1212
package: package(),
1313
deps: deps(),
1414
escript: escript(),
15-
name: "chr",
15+
name: "CHR",
1616
source_url: "https://github.com/ThaddeusJiang/chr",
1717
authors: ["ThaddeusJiang"],
1818
docs: [
@@ -32,7 +32,8 @@ defmodule Chr.MixProject do
3232
# Run "mix help deps" to learn about dependencies.
3333
defp deps do
3434
[
35-
{:owl, "~> 0.8"},
35+
{:owl, "~> 0.9"},
36+
{:ucwidth, "~> 0.2"},
3637
{:ex_doc, "~> 0.14", only: :dev, runtime: false}
3738
]
3839
end

mix.lock

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
66
"makeup_erlang": {:hex, :makeup_erlang, "0.1.4", "29563475afa9b8a2add1b7a9c8fb68d06ca7737648f28398e04461f008b69521", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f4ed47ecda66de70dd817698a703f8816daa91272e7e45812469498614ae8b29"},
77
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
8-
"owl": {:hex, :owl, "0.8.0", "0ef925cb784311093d4e3734822960cbdbdb13b095d748bb5bc82abcd5b56732", [:mix], [], "hexpm", "0a5586ceb1a12f4bbda90e330c20e6ea034552335d09466c10e4218c98977529"},
8+
"owl": {:hex, :owl, "0.9.0", "9b33d64734bd51d3fc1d6ed01b12f8c2ed23e1fbf8c43658a6dfbff62578bd03", [:mix], [{:ucwidth, "~> 0.2", [hex: :ucwidth, repo: "hexpm", optional: true]}], "hexpm", "cd70b55327985f8f24d38cb7de5bf8a8d24040e1b49cca2345508f8119ce81fd"},
9+
"ucwidth": {:hex, :ucwidth, "0.2.0", "1f0a440f541d895dff142275b96355f7e91e15bca525d4a0cc788ea51f0e3441", [:mix], [], "hexpm", "c1efd1798b8eeb11fb2bec3cafa3dd9c0c3647bee020543f0340b996177355bf"},
910
}

0 commit comments

Comments
 (0)