1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
|
# hackernews-TUI
`hackernews_tui` is a fast and [customizable](https://github.com/aome510/hackernews-TUI/blob/main/docs/config.md) application for browsing Hacker News on the terminal.
`hackernews_tui` is written in Rust with the help of [Cursive TUI library](https://github.com/gyscos/cursive/). It uses [HN Algolia APIs](https://hn.algolia.com/api/) and [HN Official APIs](https://github.com/HackerNews/API) to get Hacker News data.
## Table of Contents
- [Install](#install)
- [Binaries](#binaries)
- [Using Cargo](#using-cargo)
- [Docker Image](#docker-image)
- [Building from source](#building-from-source)
- [macOS](#macos)
- [Arch Linux](#arch-linux)
- [NetBSD](#netbsd)
- [Examples](#examples)
- [Demo](#demo)
- [Default Shortcuts](#default-shortcuts)
- [Global key shortcuts](#global-key-shortcuts)
- [Edit key shortcuts](#edit-key-shortcuts)
- [Key shortcuts for each View](#key-shortcuts-for-each-view)
- [Story View](#story-view-shortcuts)
- [Article View](#article-view-shortcuts)
- [Comment View](#comment-view-shortcuts)
- [Search View](#search-view-shortcuts)
- [Configuration](#configuration)
- [Authentication](#authentication)
- [Logging](#logging)
- [Roadmap](#roadmap)
## Install
### Binaries
Application's prebuilt binaries can be found in the [Releases Page](https://github.com/aome510/hackernews-TUI/releases).
### Using cargo
Install the latest version from [crates.io](https://crates.io/crates/hackernews_tui) by running `cargo install hackernews_tui --locked`.
### Docker image
You can download the binary image of the latest build from the `master` branch by running
```shell
docker pull aome510/hackernews_tui:latest
```
then run
```shell
docker run -it aome510/hackernews_tui:latest
```
to run the application. You can also use your local configuration file when running the image by running
```shell
docker run --rm -v ${CONFIG_FILE_PATH}:/app/hn-tui.toml -it aome510/hackernews_tui:latest
```
with `${CONFIG_FILE_PATH}` is the path to the local configuration file.
#### Building from source
Run
```shell
git clone https://github.com/aome510/hackernews-TUI.git
cd hackernews-TUI
cargo build --release
```
to build the application, then run
```shell
./target/release/hackernews_tui
```
to run the application, or
```shell
ln -sf $PWD/target/release/hackernews_tui /usr/local/bin
```
to link the executable binary to `/usr/local/bin` folder.
### Windows
#### Via Scoop
Run `scoop install hackernews-tui` to install the application.
### macOS
#### Via MacPorts
Run `sudo port install hackernews-tui` to install the application.
### Arch Linux
Run `yay -S hackernews_tui` to install the application as an AUR package.
### NetBSD
#### Using the package manager
```shell
pkgin install hackernews-tui
```
#### Building from source
```shell
cd /usr/pkgsrc/www/hackernews-tui
make install
```
## Examples
### Demo
Demo videos of `hackernews_tui` `v0.9.0` are available on [youtube](https://www.youtube.com/watch?v=m5O5QIlRFpc) and [asciinema](https://asciinema.org/a/459196)
[![asciicast](https://asciinema.org/a/459196.svg)](https://asciinema.org/a/459196)
### Story View
![Example of a Story View](https://user-images.githubusercontent.com/40011582/147393397-71991e48-cba6-4f89-9d28-cafbc0143c42.png)
### Article View
![Example of an Article View](https://user-images.githubusercontent.com/40011582/147393483-06b57c07-3fa3-49ec-b238-a2d67905610d.png)
### Search View
![Example of a Search View](https://user-images.githubusercontent.com/40011582/147393493-41d52d9f-65cd-4f63-bf76-c11d9bea1f49.png)
### Comment View
![Example of a Comment View](https://user-images.githubusercontent.com/40011582/147393459-641dd6c3-3564-472c-83cd-e1865339c861.png)
## Default Shortcuts
In each `View`, press `?` to see a list of supported keyboard shortcuts and their functionalities.
![Example of a Help View](https://user-images.githubusercontent.com/40011582/147393555-5ca346ca-b59a-4a7f-ab53-b1ec7025eca4.png)
The below sections will list the application's default shortcuts, which can be customized by changing the [key mappings](https://github.com/aome510/hackernews-TUI/blob/main/docs/config.md#keymap) in the user's config file.
For more information about configuring the application's key mappings or defining custom shortcuts, please refer to the [config documentation](https://github.com/aome510/hackernews-TUI/blob/main/doc/config.md#keymap).
### Global shortcuts
| Command | Description | Default Shortcut |
| ----------------------- | ----------------------- | ------------------ |
| `open_help_dialog` | Open the help dialog | `?` |
| `close_dialog` | Close a dialog | `esc` |
| `quit` | Quit the application | `[q, C-c]` |
| `goto_previous_view` | Go to the previous view | `[backspace, C-p]` |
| `goto_search_view` | Go to search view | `[/, C-s]` |
| `goto_front_page_view` | Go to front page view | `F1` |
| `goto_all_stories_view` | Go to all stories view | `F2` |
| `goto_ask_hn_view` | Go to ask HN view | `F3` |
| `goto_show_hn_view` | Go to show HN view | `F4` |
| `goto_jobs_view` | Go to jobs view | `F5` |
### Edit shortcuts
| Command | Description | Default Shortcut |
| ---------------------- | -------------------------------- | ---------------- |
| `move_cursor_left` | Move cursor to left | `[left, C-b]` |
| `move_cursor_right` | Move cursor to right | `[right, C-f]` |
| `move_cursor_to_begin` | Move cursor to the begin of line | `[home, C-a]` |
| `move_cursor_to_end` | Move cursor to the end of line | `[end, C-e]` |
| `backward_delete_char` | Delete backward a character | `backspace` |
## Scrolling shortcuts
| Command | Description | Default Shortcut |
| ----------- | ----------------------- | ---------------- |
| `up` | Scroll up | `[k, up]` |
| `down` | Scroll down | `[j, down]` |
| `page_down` | Scroll up half a page | `[d, page_down]` |
| `page_up` | Scroll down half a page | `[u, page_up]` |
| `top` | Scroll to top | `[g, home]` |
| `bottom` | Scroll to bottom | `[G, end]` |
### Shortcuts for each `View`
#### Story View shortcuts
| Command | Description | Default Shortcut |
| ------------------------------ | ----------------------------------------------------- | ---------------- |
| `next_story` | Focus the next story | `j` |
| `prev_story` | Focus the previous story | `k` |
| `next_story_tag` | Go to the next story tag | `l` |
| `previous_story_tag` | Go to the previous story tag | `h` |
| `goto_story` | Focus the {story_id}-th story | `{story_id} g` |
| `goto_story_comment_view` | Go the comment view associated with the focused story | `enter` |
| `open_article_in_browser` | Open in browser the focused story's article | `o` |
| `open_article_in_article_view` | Open in article view the focused story's article | `O` |
| `open_story_in_browser` | Open in browser the focused story | `s` |
| `next_page` | Go to the next page | `n` |
| `prev_page` | Go the previous page | `p` |
| `cycle_sort_mode` | Cycle story sort mode | `d` |
#### Article View shortcuts
| Command | Description | Default Shortcut |
| --------------------------- | -------------------------------------- | ---------------- |
| `open_article_in_browser` | Open article in browser | `a` |
| `open_link_in_browser` | Open in browser {link_id}-th link | `{link_id} o` |
| `open_link_in_article_view` | Open in article view {link_id}-th link | `{link_id} O` |
| `open_link_dialog` | Open link dialog | `l` |
##### Link dialog shortcuts
| Command | Description | Default Shortcut |
| --------------------------- | ------------------------------------- | ---------------- |
| `next` | Focus next link | `[j, down]` |
| `prev` | Focus previous link | `[k, up]` |
| `open_link_in_browser` | Open in browser the focused link | `[o, enter]` |
| `open_link_in_article_view` | Open in article view the focused link | `O` |
#### Comment View shortcuts
| Command | Description | Default Shortcut |
| ------------------------------ | ------------------------------------------------------------------------------- | ---------------- |
| `next_comment` | Focus the next comment | `j` |
| `prev_comment` | Focus the previous comment | `k` |
| `next_leq_level_comment` | Focus the next comment with smaller or equal level | `l` |
| `prev_leq_level_comment` | Focus the previous comment with smaller or equal level | `h` |
| `next_top_level_comment` | Focus the next top level comment | `n` |
| `prev_top_level_comment` | Focus the previous top level comment | `p` |
| `parent_comment` | Focus the parent comment (if exists) | `u` |
| `toggle_collapse_comment` | Toggle collapsing the focused item | `tab` |
| `vote` | Toggle voting the focused item (**requires [authentication](#authentication)**) | `v` |
| `open_article_in_browser` | Open in browser the discussed article | `a` |
| `open_article_in_article_view` | Open in article view the discussed article | `A` |
| `open_story_in_browser` | Open in browser the discussed story | `s` |
| `open_comment_in_browser` | Open in browser the focused comment | `c` |
| `open_link_in_browser` | Open in browser the {link_id}-th link in the focused comment | `{link_id} o` |
| `open_link_in_article_view` | Open in article view the {link_id}-th link in the focused comment | `{link_id} O` |
#### Search View shortcuts
In `SearchView`, there are two modes: `Navigation` and `Search`. The default mode is `Search`.
`Search` mode is similar to Vim's insert mode, in which users can input a query string.
`Navigation` mode allows the `SearchView` to behave like a `StoryView` of matched stories.
`SearchView`-specific key shortcuts:
| Command | Description | Default Shortcut |
| -------------------- | ------------------------------------------ | ---------------- |
| `to_search_mode` | Enter `Search` mode from `Navigation` mode | `i` |
| `to_navigation_mode` | Enter `Navigation` mode from `Search` mode | `<esc>` |
## Configuration
By default, `hackernews-tui` will look for the `hn-tui.toml` user-defined config file inside
- the [user's config directory](https://docs.rs/dirs-next/latest/dirs_next/fn.config_dir.html)
- `.config` directory inside the [user's home directory](https://docs.rs/dirs-next/latest/dirs_next/fn.home_dir.html)
If not found such file, the application will fall back to use a set of [default configurations](https://github.com/aome510/hackernews-TUI/blob/main/examples/hn-tui.toml).
User can also specify the path to config file when running the application with `-c` or `--config` option.
```shell
hackernews_tui -c ~/.config/hn-tui.toml
```
For further information about the application's configurations, please refer to the [example config file](https://github.com/aome510/hackernews-TUI/blob/main/examples/hn-tui.toml) and the [config documentation](https://github.com/aome510/hackernews-TUI/blob/main/config.md).
## Authentication
Users can authenticate their account by specifying `username` and `password` inside the `hn-auth.toml` file:
```toml
username=""
password=""
```
By default, the authentication file should be inside the same folder as the the general configuration file (`hn-tui.toml`), which can be configured by specifying the `-a` or `--auth` option.
## Logging
`hackernews-tui` uses `RUST_LOG` environment variable to define the application's [logging level](https://docs.rs/log/0.4.14/log/enum.Level.html) (default to be `INFO`).
By default, the application creates the `hn-tui.log` log file inside the [user's cache directory](https://docs.rs/dirs-next/latest/dirs_next/fn.cache_dir.html), which can be configured by specifying the `-l` or `--log` option.
## Roadmap
- [x] make all commands customizable
- [x] add a `View` to read the linked story in reader mode on the terminal. A list of possible suggestion can be found [here](https://news.ycombinator.com/item?id=26930466)
- [x] add commands to navigate parent comments and collapse a comment
- [x] make all the configuration options optional
- integrate [HackerNews Official APIs](https://github.com/HackerNews/API) for real-time updating, lazy-loading comments, and sorting stories
- [x] lazy-loading comments
- [x] front-page stories like the official site
- [ ] real-time updating
- [x] implement smarter lazy-loading comment functionality
- add crediential support to allow
- [x] authentication
- [x] upvote/downvote
- [ ] add comment
- [ ] post
- improve application's UI
- [x] improve the application's overall look
- [x] include useful font-highliting
- [x] rewrite the theme parser to support more themes and allow to parse themes from known colorschemes
- [ ] add some extra transition effects
- improve the keybinding handler
- [x] allow to bind multiple keys to a single command
- [ ] add prefix key support (emacs-like key chaining - `C-x C-c ...`)
|