Skip to content

Commit

Permalink
feat/bindings keymaps (#93)
Browse files Browse the repository at this point in the history
* feat: add keymaps docs and update bindings

* fix: tweak isr config for gh badge

* fix: add tweets

* fix: move nebulagraph to end of adapter list
  • Loading branch information
tconbeer authored Jun 27, 2024
1 parent c63bb12 commit 18af2fd
Show file tree
Hide file tree
Showing 20 changed files with 193 additions and 11 deletions.
4 changes: 3 additions & 1 deletion src/docs/bindings.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
---
title: Key Bindings
title: "Reference: Default Bindings"
menuOrder: 200
---

<script>
import Key from "$lib/components/key.svelte"
</script>

Harlequin uses keymaps to define sets of key bindings in the app. Below is a reference for the bindings from the default keymap (called `vscode`). For more information on customizing key bindings, see the [keymaps](keymaps) page.

## General Bindings

- <Key>ctrl+q</Key> Quit Harlequin
Expand Down
2 changes: 1 addition & 1 deletion src/docs/files/local.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: Local Files
menuOrder: 3
---

Harlequin's Data Catalog will show remote files in a second tab in the Data Catalog if Harlequin is initialized with the `--show-files` option (alias `-f`). `--show-files` takes an absolute or relative file path to a directory as its argument:
Harlequin's Data Catalog will show local files in a second tab in the Data Catalog if Harlequin is initialized with the `--show-files` option (alias `-f`). `--show-files` takes an absolute or relative file path to a directory as its argument:

For example, an absolute path:

Expand Down
8 changes: 7 additions & 1 deletion src/docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,16 @@ Other adapters can be installed using `pip install <adapter package>` or `pipx i

## Getting Help

To view these docs from within the app, press <Key>F1</Key>.

To view all command-line options for Harlequin and all installed adapters, after installation, simply type:

```bash
harlequin --help
```

To view a list of all key bindings (keyboard shortcuts) within the app, press <Key>F1</Key>. You can also view this list outside the app [here](bindings).
See the [Troubleshooting](troubleshooting/index) guide for help with key bindings, appearance issues, copy-paste, etc.

[GitHub Issues](https://github.com/tconbeer/harlequin/issues) are the best place to report bugs.

[GitHub Discussions](https://github.com/tconbeer/harlequin/discussions) are a good place to ask questions, request features, and more.
89 changes: 89 additions & 0 deletions src/docs/keymaps/config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Creating a Keymap
menuOrder: 8
---

<script>
import Key from "$lib/components/key.svelte"
import keys_app from "$lib/assets/docs/keys-app.png"
import keys_app_edit from "$lib/assets/docs/keys-app-edit.png"
</script>

Keymaps can be defined in Harlequin [config files](../config-file), under the `keymaps` key. You can create these keymaps manually in a text editor, or by using the [Harlequin Keys App](#keys-app).

## What is a Keymap?
In a config file, a keymap is a "[array of tables](https://toml.io/en/v1.0.0#array-of-tables)", where each table defines a key binding. A simple keymap looks like this:

```toml
[[keymaps.more_arrows]]
keys="w"
action="results_viewer.cursor_up"
key_display="⬆/w"

[[keymaps.more_arrows]]
keys="a"
action="results_viewer.cursor_left"
key_display="⬅/a"

[[keymaps.more_arrows]]
keys="s,j"
action="results_viewer.cursor_down"
key_display="⬇/s"

[[keymaps.more_arrows]]
keys="d"
action="results_viewer.cursor_right"
key_display="➡/d"
```

This keymap is named `more_arrows`, and it maps the keys <Key>w</Key>, <Key>a</Key>, <Key>s</Key>, and <Key>d</Key> to actions that move the cursor in the Results Viewer. The arrow keys are already mapped to these actions in the default keymap, so this keymap is a good example of [extending the default keymap](usage#extending-a-keymap).

The items in each table are as follows:

### Keys

The `keys` item is a string that must be a comma-separated list of Textual virtual key names. These are usually intuitive names like `enter` and `ctrl+f`, but depending on your terminal and shell, many keypresses will be aliased to different key names by the time they reach Harlequin. The best way to ensure the correct key name is to use the [Keys App](#keys-app).

### Action

The `action` item is a string that must be equal to the name of a Harlequin Action. A full list of action names can be found in the Harlequin [source code](https://github.com/tconbeer/harlequin/blob/main/src/harlequin/actions.py). All actions are also listed (with aliased/formatted names) in the [Keys App](#keys-app).

Actions are context-specific, so they are already scoped to either the entire app or a specific widget. Those that are scoped to a widget have names that take the form `<widget_name>.<action_name>`.

### Key Display

Harlequin's Footer can display currently-active (in-scope) key bindings. Many bindings are hidden by default. By including a `key_display` item in each table, Harlequin will show the binding, optionally with a custom symbol.

## Keys App

Harlequin ships with an app that makes it easy to create your own custom keymap. To start the app, start harlequin with the `--keys` option:

```bash
harlequin --keys
```

The app will load the currently-active config (from discovered TOML files, in the same manner as Harlequin) and show a list of all configured key bindings (using the default profile and its specified keymaps). You can load the Keys App with options that specify a config file, profile, and/or keymap name if you would like, using command-line options:

```bash
harlequin --config-path ~/my-config.toml --profile Foo --keys
```

**Note:** the `--config-path`, `--profile`, `--keymap-name`, and `--theme` options must be declared **before** the `--keys` option for this to work.

<div class="flex flex-wrap justify-center py-2">
<figure>
<img src={keys_app} alt="Screenshot of the main screen of the Keys App." class="h-auto w-full max-h-80">
<figcaption class="text-center text-sm text-purple font-bold">The main screen of the Keys App.</figcaption>
</figure>
</div>

In the app, you can use the arrow keys to scroll up and down the list of bindings, then press <Key>enter</Key> to edit a binding. You can replace an existing key, or add or remove keys that are bound to each action by using the buttons in the Edit modal.

<div class="flex flex-wrap justify-center py-2">
<figure>
<img src={keys_app_edit} alt="Screenshot of the Edit modal of the Keys App." class="h-auto w-full max-h-80">
<figcaption class="text-center text-sm text-purple font-bold">The Edit modal of the Keys App.</figcaption>
</figure>
</div>

After editing bindings, press <Key>ctrl+q</Key> to quit the Keys App. You will be prompted for a config file location and a keymap name. Remember this name -- you will need it in the next step, when configuring Harlequin to use your keymap. If you select `Save + Quit`, Harlequin will write the full keymap to the location you specify.
19 changes: 19 additions & 0 deletions src/docs/keymaps/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
title: Customizing Key Bindings
menuOrder: 7
---

## About Key Bindings and Keymaps

A **key binding** associates a key press, within a context, to an action.

A **keymap** is a named set of key bindings.

Harlequin gets all of its key bindings from the keymaps it discovers and loads when it starts. These keymaps are loaded either from plug-ins (installed Python packages) or TOML config files. Harlequin ships with a single keymap plug-in that defines all of its default bindings. That default keymap is called `vscode`, since many of its bindings mimic those in the popular text editor.

## Changing Key Bindings

Changing key bindings in Harlequin is a two-step process:

1. Install a keymap plug-in or [create](config) a new keymap in a config file.
2. [Select](usage) the keymap when starting Harlequin.
36 changes: 36 additions & 0 deletions src/docs/keymaps/usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
title: Selecting Keymaps
menuOrder: 9
---

After you have [created a keymap](config) or installed a keymap plug-in, you need to configure Harlequin to use that keymap.

## Replacing the Default Keymap

If you create a keymap with the [Keys App](config#keys-app), or if you install a plug-in that defines a complete keymap, then you should specify **only** that keymap when you start Harlequin. You can select a keymap using the `--keymap-name` CLI option (or in your config file, see below):

```bash
harlequin --keymap-name "my-complete-keymap"
```

## Extending a Keymap

Alternatively, you can create a partial keymap that only specifies a subset of bindings. Harlequin can load multiple keymaps and merge them by unioning the bindings found in all the configured keymaps (this may cause some conflicts and undesired behavior). To extend a keymap, specify multiple keymaps by repeating the command-line option. For example, to extend the default `vscode` keymap with the `more_arrows` keymap example from the previous page:

```bash
harlequin --keymap-name "vscode" --keymap-name "more_arrows"
```

## Using Config Files and Profiles

You can also use a Profile to define the keymaps loaded by Harlequin, instead of repeating the CLI option every time. See [config file](../config-file) for more information. An example of a config file with two profiles, equivalent to the options above:

```toml
default_profile = "my-first-profile"

[profiles.my-first-profile]
keymap_name = ["my-complete-keymap"]

[profiles.my-second-profile]
keymap_name = ["vscode", "more_arrows"]
```
2 changes: 1 addition & 1 deletion src/docs/nebulagraph/index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "Adapter: NebulaGraph"
menuOrder: 100
menuOrder: 170
---

The NebulaGraph adapter was contributed by community member Wey Gu. You can view the source for the adapter on [GitHub](https://github.com/wey-gu/harlequin-nebulagraph).
Expand Down
2 changes: 1 addition & 1 deletion src/docs/transactions.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Managing Transactions
menuOrder: 7
menuOrder: 19
---

<script>
Expand Down
Binary file added src/lib/assets/docs/keys-app-edit.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/docs/keys-app.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/lib/assets/tweets/TanelPoder.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Binary file added src/lib/assets/tweets/adrianmg.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Empty file.
Empty file.
4 changes: 2 additions & 2 deletions src/routes/+layout.server.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const config = {
isr: {
expiration: 60 * 60 * 4,
expiration: 60 * 60,
},
};

Expand All @@ -16,7 +16,7 @@ export async function load({ fetch }) {
const request = new Request(endpoint, options);
const response = await fetch(request);
if (!response.ok) {
return {forks_count: 62, stargazers_count: 2482};
return {forks_count: 72, stargazers_count: 3239};
}
const body = await response.json();
const data = (({ forks_count, stargazers_count }) => ({
Expand Down
8 changes: 6 additions & 2 deletions src/routes/docs/[topic]/[[page]]/+page.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { error } from "@sveltejs/kit";
import { error, redirect } from "@sveltejs/kit";

export async function load({ params }) {
try {
Expand All @@ -13,6 +13,10 @@ export async function load({ params }) {
meta: page.metadata,
};
} catch (e) {
error(404, `Could not find ${params.topic}/${params.page}`);
if (!params.page) {
redirect(301, `/docs/${params.topic}/index`)
} else {
error(404, `Could not find ${params.topic}/${params.page}`);
}
}
}
25 changes: 25 additions & 0 deletions src/routes/tweets.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
import _WaylonWalker from "$lib/assets/tweets/_WaylonWalker.jpg";
import KhuyenTran16 from "$lib/assets/tweets/KhuyenTran16.jpg";
import joshptemple from "$lib/assets/tweets/joshptemple.png";
import adrianmg from "$lib/assets/tweets/adrianmg.jpg";
import TanelPoder from "$lib/assets/tweets/TanelPoder.jpg";
const tweets: Tweet[] = [
{
Expand Down Expand Up @@ -140,6 +142,29 @@
created_at: "9:01 AM · Jan 5, 2024",
src: "https://twitter.com/KhuyenTran16/status/1743301579669696758",
},
{
profile: {
name: "Tanel Poder",
handle: "TanelPoder",
src: "https://twitter.com/TanelPoder",
img_src: TanelPoder,
},
body: `<p lang="en" dir="ltr">Harlequin: The SQL IDE for Your Terminal (works also with DuckDB!)<br><a style="color: blue; text-decoration: underline" href="https://harlequin.sh">harlequin.sh</a> <img alt="harlequin screenshot" src="https://pbs.twimg.com/media/GQPUTOWXIAADrpR?format=jpg&amp;name=small" >`,
created_at: "7:45 PM · Jun 16, 2024",
src: "https://twitter.com/TanelPoder/status/1802517863275643377",
},
{
profile: {
name: "Adrián Mato 🐙",
handle: "adrianmg",
src: "https://twitter.com/adrianmg",
img_src: adrianmg,
},
body: `<p lang="en" dir="ltr">What is this beauty <a style="color: blue; text-decoration: underline" href="https://harlequin.sh">harlequin.sh</a> <img alt="harlequin screenshot" src="https://pbs.twimg.com/media/GQUUIEAb0AADSUq?format=jpg&amp;name=small" >`,
created_at: "7:02 PM · Jun 17, 2024",
src: "https://x.com/adrianmg/status/1802869367753056498",
},
// AFTER ADDING CARDS, UPDATE THE CONFIG IN tailwind.config.js TO KEEP SCROLLING SMOOTH.
];
</script>

Expand Down
5 changes: 3 additions & 2 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export default {
250: "2.5",
},
animation: {
"horizontal-scroll": "horizontal-scroll 30s linear infinite",
// 3s * N cards
"horizontal-scroll": "horizontal-scroll 36s linear infinite",
},
keyframes: {
"horizontal-scroll": {
Expand All @@ -29,7 +30,7 @@ export default {
"100%": {
transform:
// 328px (320 + 8 gap) * n cards
"translateX(-3280px)",
"translateX(-3936px)",
},
},
},
Expand Down

0 comments on commit 18af2fd

Please sign in to comment.