Skip to content

KarimAziev/igist

https://melpa.org/packages/igist-badge.svg https://stable.melpa.org/packages/igist-badge.svg https://img.shields.io/badge/license-GPL-brightgreen.svg

About

igist is a modern package that aims to help you never leave Emacs to manage your GitHub gists.

./igist-table-demo.gif

./igist-demo.gif

igist

Requirements

Installation

MELPA

igist is available on MELPA.

To get started, enable installing packages from MELPA:

(require 'package)
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(package-initialize)

To fetch the list of packages you can do:

<M-x> package-refresh-contents

And after that igist can be installed with:

<M-x> package-install igist

Manually

Download the repository and it to your load path in your init file:

(add-to-list 'load-path "/path/to/igist")
(require 'igist)

With use-package

(use-package igist
  :bind (("M-o" . igist-dispatch)))

Or if you use straight.el:

(use-package igist
  :bind (("M-o" . igist-dispatch))
  :straight (igist
             :repo "KarimAziev/igist"
             :type git
             :host github))

Auth

igist manages authentication through two customizable variables:

  • igist-current-user-name: This variable should be set to a string containing your GitHub username.
  • igist-auth-marker: This variable can either be a string containing the OAuth token or a symbol indicating where to fetch the OAuth token.

Setting Up token

Firsly, you need to ensure that you have a GitHub API token with scope gist:

  1. Log in to your GitHub account and navigate to settings.
  2. Select the Developer settings option on the bottom of the sidebar.
  3. Here you’ll see a Personal access tokens section, click on it.
  4. Click on “Generate new token”, give your token a descriptive name.
  5. Ensure the “gist” scope is checked, this will give igist the necessary permissions it needs to manage your gists.
  6. Click on Generate token at the bottom of the page. Be sure to copy your new personal access token now as you cannot see it again.

After getting your token, you can supply it to igist in one of two ways.

Secure Way: Using auth-sources

Emacs auth-sources provide a secure way to store your GitHub username and OAuth token.

To employ this method, set igist-auth-marker to the symbol igist:

(setq igist-auth-marker 'igist)

Next, add an entry to your auth-sources:

machine api.github.com login YOUR-GITHUB-USERNAME^igist password YOUR-GITHUB-TOKEN

You can add this entry to your ~/.authinfo.gpg file (recommended for secure, encrypted storage) or ~/.authinfo (see variable auth-sources).

You can read more in ghub manual, as igist relies on the provided API.

Insecure way

While not recommended due to security issues, you can set igist-auth-marker and igist-current-user-name in your Emacs config file:

(setq igist-current-user-name "your-github-username")
(setq igist-auth-marker "your-github-oauth-token")

Example with use-package.

(use-package igist
  :config
  (let ((default-directory user-emacs-directory))
    (condition-case nil
        (progn (setq igist-current-user-name
                     (car-safe
                      (process-lines "git"
                                     "config"
                                     "user.name")))
               (setq igist-auth-marker
                     (or (ignore-errors
                           (car-safe (process-lines "git" "config"
                                                    "github.oauth-token")))
                         igist-auth-marker)))
      (error (message "Igist-current-user-name cannot setted")))))

Important

In this method, your OAuth token will be stored as plain text in your emacs config file, which is insecure. Ensure your config file permissions are appropriately set to prevent unauthorized access.

Usage

With the authentication properly configured, you can now use igist. The simplest way is to invoke a transient popup with the list of available commands for the current buffer:

  • M-x igist-dispatch - in igists buffers it is bound to M-o.

List gists

There are two ways in which gists can be presented - as a table or as minibuffer completions.

Table

  • M-x igist-list-gists - to display gists of logged GitHub user.
  • M-x igist-explore-public-gists - list public gists sorted by most recently updated to least recently updated. ./igist-explore-demo.png
  • M-x igist-list-other-user-gists - to display public gists of non-logged user.

This commands render and load gists with pagination. To stop or pause loading use command igist-list-cancel-load (default keybinding is K).

KeyDescriptionCommand
RETedit gist at pointigist-list-edit-gist-at-point-async
v or C-jview gist at pointigist-list-view-current
<backtab>toggle all childrenigist-toggle-all-children
<tab>toggle row children at pointigist-toggle-row-children-at-point
+add file to gistigist-list-add-file
-delete current filenameigist-delete-current-filename
Ddelete current gistigist-delete-current-gist
Sstar gistigist-star-gist
Uunstar gistigist-unstar-gist
aadd commentigist-add-comment
cload commentsigist-load-comments
dedit descriptionigist-list-edit-description
ffork gistigist-fork-gist
wcopy gist urligist-copy-gist-url
rbrowse gistigist-browse-gist
Lclone gistigist-clone-gist
?open transient menu with main commandsigist-dispatch
Copen transient menu for editing UIigist-table-menu
/open transient menu for filteringigist-filters-menu
Kcancel loadigist-list-cancel-load
grefresh gistsigist-list-refresh
ssort gistigist-tabulated-list-sort
Gforce rerenderigist-tabulated-list-revert
}widen current columnigist-tabulated-list-widen-current-column
{narrow current columnigist-tabulated-list-narrow-current-column
M-] or M-}swap column with the next oneigist-swap-current-column
M-[ or M-{swap column with the previous oneigist-swap-current-column-backward
C-M-nforward gist and previewigist-list-forward-row-and-preview
C-M-pbackward gist and previewigist-list-backward-row-and-preview
nmove to next linenext-line
pmove to previous lineprevious-line
C-M-fforward to next columnigist-tabulated-forward-column
C-M-bmove to the previous columnigist-tabulated-backward-column

To customize these keys, see the variable igist-list-mode-map.

You can change the width, reorder, or remove columns interactively with the transient menu - igist-table-menu. If you want to save your settings, use the command M-x igist-save-column-settings. To discard, use M-x igist-reset-columns-settings.

Minibuffer Completions

  • M-x igist-edit-list - read Gist to edit from the minibuffer.

Ivy users can also use igist-ivy-read-public-gists and igist-ivy-read-user-gists.

Edit gist

You can view, edit and save gists in buffers with igist-edit-mode. This minor mode is turned on after command igist-edit-gist and igist-edit-list.

KeyCommand
M-otransient popup
C-c C-csave and exit
C-c 'save and exit
C-x C-ssave without exiting

To customize these keys see the variable igist-edit-mode-map.

List comments

This minor mode is turned on after command igist-load-comments.

In comments list mode, such commands are available:

KeyCommand
+add comment
-delete the comment at point
Ddelete the comment at point
eadd or edit
grefresh comments

To customize these keybindings edit the variable igist-comments-list-mode-map.

Editing comment

This minor mode is turned on after commands igist-edit-comment and igist-add-comment. Keymap for posting and editing comments:

KeyCommand
C-c C-cpost comment

To customize these keybindings edit the variable igist-comments-edit-mode-map.

Customization

  • igist-current-user-name: This variable should be set to a string that contains your GitHub username.
  • igist-auth-marker: This variable can either be a string that contains the OAuth token or a symbol indicating where to retrieve the OAuth token.
  • igist-message-function: A custom function for displaying messages. Should accept the same arguments as the message function.
  • igist-per-page-limit: The number of results to fetch per page. The default value is 30.
  • igist-ask-for-description: Determines when to prompt for a description before posting new gists. The default setting prompts for a description before saving a new gist.
  • igist-enable-copy-gist-url-p: Specifies whether and when to add the URL of a new or updated gist to the kill ring. The default setting is after the creation of new gists.
  • igist-list-format: Specifies the format of the user’s Tabulated Gists buffers.
  • igist-explore-format: Specifies the format of the Explore Public Gists tabulated buffers.
  • igist-immediate-resize-strategy: Controls the resizing strategy for tabulated entries when using igist-tabulated-list-widen-current-column.
  • igist-user-gists-init-collapsed: Whether the gists should be collapsed by default in user buffers.
  • igist-explore-gists-init-collapsed: Whether the gists should be collapsed by default in explore buffers.
  • igist-clone-default-directory: Default directory to use when igist-clone-gist reads destination.
  • igist-use-header-line: Whether the IGist List buffer should use a header line. If nil, an overlay will be used.
  • igist-tabulated-list-padding: Number of characters preceding each IGist List mode entry.
  • igist-tabulated-list-tty-sort-indicator-desc: Indicator for columns sorted in ascending order, for text-mode frames.
  • igist-tabulated-list-tty-sort-indicator-asc: Indicator for columns sorted in ascending order, for text-mode frames.
  • igist-tabulated-list-gui-sort-indicator-desc: Indicator for columns sorted in descending order, for gui frames.
  • igist-tabulated-list-gui-sort-indicator-asc: Indicator for columns sorted in ascending order, for gui frames.

Comparison with other Emacs Gist Libraries

Several Emacs packages for GitHub gists already exist (gist.el, jist.el, yagist.el).

igist not only includes the core functionalities of managing gists - such as editing, listing, and creating - but also introduces many new features.

  • Transient Command Interface: By adopting the transient command interface, igist provides context-aware actions for managing GitHub Gists. The use of transient interfaces leads to smoother task flows, reduces the need for keystrokes, and offers a more intuitive user experience.
  • Asynchronous Advanced Rendering: igist presents advanced rendering capabilities, including incremental and asynchronous loading and rendering. This ensures that the Emacs interface remains responsive even when handling a large number of Gists.
  • Customization on the Fly: igist focuses on providing an interface for live configuration of how gists should be displayed. Users can adjust column width and alignment, alter sortability, and add, rename or remove columns on the fly.
  • Incremental Filtering: This feature allows filtering of Gists by filename, description, or programming language.