*cord.txt*              For NVIM v0.6.0             Last change: 2025 March 29

==============================================================================
Table of Contents                                     *cord-table-of-contents*

1. Configuration                                          |cord-configuration|
  - Editor                                         |cord-configuration-editor|
  - Display                                       |cord-configuration-display|
  - Timestamp                                   |cord-configuration-timestamp|
  - Idle                                             |cord-configuration-idle|
  - Text                                             |cord-configuration-text|
  - Variables                                   |cord-configuration-variables|
  - Hooks                                           |cord-configuration-hooks|
  - Plugins                                       |cord-configuration-plugins|
  - Advanced                                     |cord-configuration-advanced|
  - Text Options                             |cord-configuration-text-options|
  - Buttons                                       |cord-configuration-buttons|
  - Assets                                         |cord-configuration-assets|
  - Smart Idle                                 |cord-configuration-smart-idle|
  - Custom Variables                     |cord-configuration-custom-variables|
  - User Commands                           |cord-configuration-user-commands|
  - Cursor Update Mode                 |cord-configuration-cursor-update-mode|
  - Options Table                           |cord-configuration-options-table|
  - ActivityManager Methods       |cord-configuration-activitymanager-methods|
  - Activity Options                     |cord-configuration-activity-options|
  - Useful Functions                     |cord-configuration-useful-functions|
2. Custom Assets                                          |cord-custom-assets|
  - Structure                                   |cord-custom-assets-structure|
  - Asset Keys                                 |cord-custom-assets-asset-keys|
  - Asset Options                           |cord-custom-assets-asset-options|
  - Examples                                     |cord-custom-assets-examples|
  - Overriding Defaults               |cord-custom-assets-overriding-defaults|
  - Tip                                               |cord-custom-assets-tip|
3. Plugins                                                      |cord-plugins|
  - Enabling Plugins                           |cord-plugins-enabling-plugins|
  - Available Plugins                         |cord-plugins-available-plugins|
4. Examples                                                    |cord-examples|
  - Features                                          |cord-examples-features|
  - Quick Start                                    |cord-examples-quick-start|
  - Themes                                              |cord-examples-themes|
  - Documentation                                |cord-examples-documentation|
  - Versioning                                      |cord-examples-versioning|
  - Contributing                                  |cord-examples-contributing|
  - Support the Project                    |cord-examples-support-the-project|
  - Build From Source                        |cord-examples-build-from-source|

==============================================================================
1. Configuration                                          *cord-configuration*

A comprehensive guide to configuring the Cord plugin to your liking. All
options are set through the `setup()` function:

>lua
    require('cord').setup {
        -- Your configuration options go here
    }
<

If you prefer to start with a clean slate, you can copy the
|cord-default-configuration| below and modify it to your liking. Remember, you
only need to specify the options you want to change; any unspecified options
will use their default values.

Here’s the complete default configuration for Cord. You can use this as a
starting point for your own setup.

Expand to view default configuration ~

>lua
    {
      enabled = true,
      log_level = vim.log.levels.OFF,
      editor = {
        client = 'neovim',
        tooltip = 'The Superior Text Editor',
        icon = nil,
      },
      display = {
        theme = 'default',
        flavor = 'dark',
        swap_fields = false,
        swap_icons = false,
      },
      timestamp = {
        enabled = true,
        reset_on_idle = false,
        reset_on_change = false,
      },
      idle = {
        enabled = true,
        timeout = 300000,
        show_status = true,
        ignore_focus = true,
        unidle_on_focus = true,
        smart_idle = true,
        details = 'Idling',
        state = nil,
        tooltip = '💤',
        icon = nil,
      },
      text = {
        default = nil,
        workspace = function(opts) return 'In ' .. opts.workspace end,
        viewing = function(opts) return 'Viewing ' .. opts.filename end,
        editing = function(opts) return 'Editing ' .. opts.filename end,
        file_browser = function(opts) return 'Browsing files in ' .. opts.name end,
        plugin_manager = function(opts) return 'Managing plugins in ' .. opts.name end,
        lsp = function(opts) return 'Configuring LSP in ' .. opts.name end,
        docs = function(opts) return 'Reading ' .. opts.name end,
        vcs = function(opts) return 'Committing changes in ' .. opts.name end,
        notes = function(opts) return 'Taking notes in ' .. opts.name end,
        debug = function(opts) return 'Debugging in ' .. opts.name end,
        test = function(opts) return 'Testing in ' .. opts.name end,
        diagnostics = function(opts) return 'Fixing problems in ' .. opts.name end,
        games = function(opts) return 'Playing ' .. opts.name end,
        terminal = function(opts) return 'Running commands in ' .. opts.name end,
        dashboard = 'Home',
      }, 
      buttons = nil,
      -- buttons = {
      --   {
      --     label = 'View Repository',
      --     url = function(opts) return opts.repo_url end,
      --   },
      -- },
      assets = nil,
      variables = nil,
      hooks = {
        ready = nil,
        shutdown = nil,
        pre_activity = nil,
        post_activity = nil,
        idle_enter = nil,
        idle_leave = nil,
        workspace_change = nil,
      },
      plugins = nil,
      advanced = {
        plugin = {
          autocmds = true,
          cursor_update = 'on_hold',
          match_in_mappings = true,
        },
        server = {
          update = 'fetch',
          pipe_path = nil,
          executable_path = nil,
          timeout = 300000,
        },
        discord = {
          reconnect = {
            enabled = false,
            interval = 5000,
            initial = true,
          },
        },
      },
    }
<


EDITOR                                             *cord-configuration-editor*

  ---------------------------------------------------------------------------------------------------------------
  Option           Type            Default                      Description
  ---------------- --------------- ---------------------------- -------------------------------------------------
  editor.client    string          'neovim'                     Client identifier. Can be 'vim', 'neovim',
                                                                'lunarvim', 'nvchad', 'astronvim', 'lazyvim', or
                                                                a custom Discord application ID

  editor.tooltip   string          'The Superior Text Editor'   Tooltip shown when hovering over editor icon

  editor.icon      string \| nil   nil                          Custom icon URL or asset ID when using custom
                                                                client ID
  ---------------------------------------------------------------------------------------------------------------

DISPLAY                                           *cord-configuration-display*

  ----------------------------------------------------------------------------------------
  Option                Type      Default   Description
  --------------------- --------- --------- ----------------------------------------------
  display.theme         string    default   Choose between different icon themes;
                                            ‘default’, ‘atom’, ‘catppuccin’

  display.flavor        string    dark      Choose between different theme flavors;
                                            typically ‘dark’, ‘light’, ‘accent’

  display.swap_fields   boolean   false     Show workspace name before filename

  display.swap_icons    boolean   false     Use editor icon as large image
  ----------------------------------------------------------------------------------------

TIMESTAMP                                       *cord-configuration-timestamp*

  ----------------------------------------------------------------------------------
  Option                      Type      Default   Description
  --------------------------- --------- --------- ----------------------------------
  timestamp.enabled           boolean   true      Show elapsed time in presence

  timestamp.reset_on_idle     boolean   false     Reset timestamp when entering idle
                                                  state

  timestamp.reset_on_change   boolean   false     Reset timestamp when presence
                                                  changes
  ----------------------------------------------------------------------------------

IDLE                                                 *cord-configuration-idle*

  ---------------------------------------------------------------------------------------------------------
  Option                 Type                       Default                           Description
  ---------------------- -------------------------- --------------------------------- ---------------------
  idle.enabled           boolean                    true                              Enable idle status
                                                                                      detection

  idle.timeout           number                     300000                            Milliseconds before
                                                                                      marking the session
                                                                                      as idle

  idle.show_status       boolean                    true                              Show idle status in
                                                                                      presence, or hide the
                                                                                      presence if false

  idle.ignore_focus      boolean                    true                              Show idle despite
                                                                                      Neovim having focus

  idle.unidle_on_focus   boolean                    true                              Unidle the session
                                                                                      when Neovim gains
                                                                                      focus

  idle.smart_idle        boolean                    true                              Enable smart idle
                                                                                      feature

  idle.details           string \| function(opts)   'Idling'                          Details shown when
                                                                                      idle

  idle.state             string \| function(opts)   nil                               State shown when idle

  idle.tooltip           string \| function(opts)   '💤'                              Tooltip shown when
                                                                                      hovering over idle
                                                                                      icon

  idle.icon              string \| function(opts)   default idle icon                 Custom icon URL or
                                                                                      asset ID
  ---------------------------------------------------------------------------------------------------------

TEXT                                                 *cord-configuration-text*

  ----------------------------------------------------------------------------------------------------------------
  Option           Type                                  Default                        Description
  ---------------- ------------------------------------- ------------------------------ --------------------------
  default          string \| function(opts) \| boolean   nil                            Default text for all
                                                                                        unspecified text options

  workspace        string \| function(opts) \| boolean   In {workspace}                 Text shown when in a
                                                                                        workspace

  viewing          string \| function(opts) \| boolean   Viewing {filename}             Text shown when viewing a
                                                                                        file

  editing          string \| function(opts) \| boolean   Editing {filename}             Text shown when editing a
                                                                                        file

  file_browser     string \| function(opts) \| boolean   Browsing files in {name}       Text shown when in a file
                                                                                        browser

  plugin_manager   string \| function(opts) \| boolean   Managing plugins in {name}     Text shown when in a
                                                                                        plugin manager

  lsp              string \| function(opts) \| boolean   Configuring LSP in {name}      Text shown when in an LSP
                                                                                        manager

  docs             string \| function(opts) \| boolean   Reading {name}                 Text shown when in a docs
                                                                                        buffer

  vcs              string \| function(opts) \| boolean   Committing changes in {name}   Text shown when in a VCS
                                                                                        buffer

  notes            string \| function(opts) \| boolean   Taking notes in {name}         Text shown when in a notes
                                                                                        buffer

  debug            string \| function(opts) \| boolean   Debugging in {name}            Text shown when in a
                                                                                        debug-related plugin
                                                                                        buffer

  test             string \| function(opts) \| boolean   Testing in {name}              Text shown when in a
                                                                                        testing-related plugin
                                                                                        buffer

  diagnostics      string \| function(opts) \| boolean   Fixing problems in {name}      Text shown when in a
                                                                                        diagnostics buffer

  games            string \| function(opts) \| boolean   Playing {name}                 Text shown when in a game
                                                                                        buffer

  terminal         string \| function(opts) \| boolean   Running commands in {name}     Text shown when in a
                                                                                        terminal buffer

  dashboard        string \| function(opts) \| boolean   'Home'                         Home
  ----------------------------------------------------------------------------------------------------------------

  Also see |cord-text-options|

VARIABLES                                       *cord-configuration-variables*

  -------------------------------------------------------------------------------------------------------------
  Option      Type                      Default   Description
  ----------- ------------------------- --------- -------------------------------------------------------------
  variables   table \| boolean \| nil   nil       Define custom variables for use in string templates.
                                                  Functions can be used to dynamically generate values. If
                                                  true, uses the default options table, if table, extends the
                                                  default table, if false, disables custom variables

  -------------------------------------------------------------------------------------------------------------

HOOKS                                               *cord-configuration-hooks*

  --------------------------------------------------------------------------------------------------------------------------------------------------
  Option                   Type                                                                                 Description
  ------------------------ ------------------------------------------------------------------------------------ ------------------------------------
  hooks.ready              function(manager) \| table<fun: function(manager), priority: number>                 Called when connected to the server
                                                                                                                and ready for communication with
                                                                                                                Discord (manager)

  hooks.shutdown           function() \| table<fun: function(), priority: number>                               Called when connection to Discord is
                                                                                                                closed

  hooks.pre_activity       function(opts) \| table<fun: function(opts), priority: number>                       Called before building activity
                                                                                                                (opts)

  hooks.post_activity      function(opts, activity) \| table<fun: function(opts, activity), priority: number>   Called after building activity, but
                                                                                                                before sending it (opts, activity)

  hooks.idle_enter         function(opts) \| table<fun: function(opts), priority: number>                       Called when entering idle state
                                                                                                                (opts)

  hooks.idle_leave         function(opts) \| table<fun: function(opts), priority: number>                       Called when leaving idle state
                                                                                                                (opts)

  hooks.workspace_change   function(opts) \| table<fun: function(opts), priority: number>                       Called when workspace changes (opts)
  --------------------------------------------------------------------------------------------------------------------------------------------------

PLUGINS                                           *cord-configuration-plugins*

  ----------------------------------------------------------------------------------------
  Option    Type                               Description
  --------- ---------------------------------- -------------------------------------------
  plugins   string[] \| table<string, table>   Extend Cord with plugins. See the Wiki for
                                               more info

  ----------------------------------------------------------------------------------------

  If you want to develop your own plugin, check out Cord’s Plugin System
  <./Plugin-System.md>

ADVANCED                                         *cord-configuration-advanced*

  -----------------------------------------------------------------------------------------------------------------------
  Option                                Type            Default     Description
  ------------------------------------- --------------- ----------- -----------------------------------------------------
  advanced.plugin.autocmds              boolean         true        Enable autocmds

  advanced.plugin.cursor_update         string          'on_hold'   When to update cursor position: 'on_move', 'on_hold',
                                                                    or 'none'. See Cursor Update Mode

  advanced.plugin.match_in_mappings     boolean         true        Whether to match against file extensions in mappings

  advanced.server.update                string          'fetch'     Default way to acquire the server executable either
                                                                    if the executable is not found or a manual update is
                                                                    requested: 'fetch' - fetch from GitHub, 'build' -
                                                                    build from source, 'none' - no-op

  advanced.server.pipe_path             string \| nil   nil         Custom IPC pipe path

  advanced.server.executable_path       string \| nil   nil         Custom server executable path

  advanced.server.timeout               number          300000      Server shutdown timeout (ms)

  advanced.discord.reconnect.enabled    boolean         false       Whether reconnection is enabled. Has minimal impact
                                                                    on performance

  advanced.discord.reconnect.interval   number          5000        Reconnection interval in milliseconds, 0 to disable

  advanced.discord.reconnect.initial    boolean         true        Whether to reconnect if initial connection fails
  -----------------------------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------

TEXT OPTIONS                                 *cord-configuration-text-options*

The `text` table allows you to customize the displayed text for different
states. You can customize it in three different ways:

1. Using simple strings:

>lua
    text = {
        editing = 'Editing a file',
        viewing = 'Viewing a file',
    }
<

1. Using functions for dynamic text:

>lua
    text = {
        editing = function(opts)
            return string.format('Editing %s', opts.filename)
        end,
    }
<

1. Using string templates (requires enabling variables):

>lua
    {
        text = {
            editing = 'Editing ${filename}',
            file_browser = 'Browsing files in ${tooltip}',
        },
        variables = true, -- Enable string templates
    }
<

You can also set a default text for all unspecified options:

>lua
    text = {
        default = 'Using Neovim',  -- This will be used for any unspecified text options, you can use functions and boolean values as well
        workspace = 'In workspace', -- This overrides the default for workspace
        -- other fields not specified will use the default value
    }
<


  To see all available options, refer to the |cord-default-configuration|.
It is also possible to use boolean values to completely disable a category:

>lua
    text = {
        workspace = '',         -- Omit the text from the activity, meaning it will only have one row of text
        games = function() end, -- Returning `nil` is the same as above
    
        file_browser = true,    -- Ignore these types of buffers and the current activity will remain unchanged
        plugin_manager = false, -- Hide the activity for these types of buffers
    
        -- Also applicable to functions
        diagnostics = function(opts)
            -- Only show diagnostics activity if there are problems, otherwise do nothing
            return #vim.diagnostics.get(vim.api.nvim_get_current_buf()) > 0 and 'Fixing problems in ' .. opts.tooltip or true
        end,
    }
<


BUTTONS                                           *cord-configuration-buttons*

Buttons can have static or dynamic labels and URLs:

>lua
    buttons = {
        {
            label = function(opts)
                return opts.repo_url and 'View Repository' or 'Website'
            end,
            url = function(opts)
                return opts.repo_url or 'https://example.com'
            end
        }
    }
<


ASSETS                                             *cord-configuration-assets*

Override icons and text for specific filetypes or filenames. Most of the
options also support functions.

>lua
    assets = {
        ['.rs'] = {
            icon = 'rust',              -- Asset name or URL
            tooltip = 'Rust',           -- Hover text
            text = 'Writing in Rust'    -- Override entire text
        },
        netrw = {
            name = 'Netrw',             -- Override asset name only
            type = 'file_browser'       -- Set asset type
        }
    }
<


  [!TIP] A detailed guide can be found in the Wiki <./Assets.md>.
Some languages cannot be identified solely by their filename or extension. In
such cases, we can utilize the `vim.filetype.add` function to add extra
patterns for filetype detection:

>lua
    vim.filetype.add {
      pattern = {
        ['.*/waybar/config'] = 'jsonc',
        ['.*/hypr/.*%.conf'] = 'hyprlang',
        -- ...
      },
    }
<


SMART IDLE                                     *cord-configuration-smart-idle*

Smart idle ensures that: - When an instance goes idle, it switches to show the
most recent active one - You’re only shown as idle when all instances are
actually idle


CUSTOM VARIABLES                         *cord-configuration-custom-variables*

The `variables` option allows you to define custom variables to be used in
string templates. These variables can be static values or functions that
dynamically generate values based on the current context. By default, the table
is populated with the |cord-options-table| but they can be overridden by
user-defined variables.

Example configuration:

>lua
    require('cord').setup {
        variables = {
            filename = 'a file',
            problems = function(opts) return #vim.diagnostic.get(0) end,
        },
        text = {
            viewing = 'Viewing ${filename} - ${problems} problems',
        }
    }
<


USER COMMANDS                               *cord-configuration-user-commands*


  [!NOTE] Autocompletion is fully supported. To see the list of all available
  features, hit `<Tab>` after typing `:Cord enable`
- `:Cord enable` - Show presence
    - `:Cord enable <feature>` - Enable a feature
- `:Cord disable` - Hide presence
    - `:Cord disable <feature>` - Disable a feature
- `:Cord toggle` - Toggle presence
    - `:Cord toggle <feature>` - Toggle a feature
- `:Cord presence` - Toggle presence display
    - `:Cord presence show` - Show presence
    - `:Cord presence hide` - Hide presence
    - `:Cord presence suppress` - Suppress presence for current Neovim session
    - `:Cord presence toggle` - Toggle presence
    - `:Cord presence toggle_suppress` - Toggle presence suppression
- `:Cord idle` - Toggle idle state
    - `:Cord idle toggle` - Toggle idle state
    - `:Cord idle show` - Show idle state
    - `:Cord idle hide` - Hide idle state
    - `:Cord idle force` - Force idle state
- `:Cord update` - Update the server executable using the configured update mode (fetch by default)
    - `:Cord update check` - Check for server updates
    - `:Cord update fetch` - Fetch the server executable from GitHub using `curl`
    - `:Cord update build` - Build the server executable using `cargo`
- `:Cord status` - Show connection status
- `:Cord version` - Show current server version
- `:Cord restart` - Restart the server
- `:Cord shutdown` - Disconnect from Discord and shutdown the server
- `:Cord health` - Validate user configuration


CURSOR UPDATE MODE                     *cord-configuration-cursor-update-mode*

The `advanced.cursor_update_mode` option controls how cursor position updates
are handled: - `'on_move'` - Uses `CursorMoved[I]` autocmd, updating on every
cursor movement. Most accurate but triggered very often - `'on_hold'` - Uses
`CursorHold[I]` autocmd, updating only after the cursor has been stationary for
`'updatetime'` milliseconds. Better performance but less accurate - `'none'` -
Disables cursor position updates entirely


OPTIONS TABLE                               *cord-configuration-options-table*

The `opts` parameter passed to all functions and hooks contains the following
information:

>lua
    {
      manager           = ActivityManager,  -- Reference to the ActivityManager instance
    
      -- File Information
      name              = string?,          -- Name associated with the current mapping, if any
      tooltip           = string?,          -- Tooltip associated with the current mapping, if any
      filename          = string,           -- Current buffer's filename
      filetype          = string,           -- Current buffer's filetype
      buftype           = string,           -- Current buffer's buftype
      is_read_only      = boolean,          -- Whether the current buffer is read-only
    
      -- Cursor Information
      cursor_line       = number,           -- Current cursor line number
      cursor_char       = number,           -- Current cursor character number
    
      -- Timestamp Information
      timestamp         = number,           -- Timestamp passed to the Rich Presence in milliseconds
    
      -- Workspace Information
      workspace         = string?,          -- Current workspace name
      workspace_dir     = string?,          -- Current workspace directory
      repo_url          = string?,          -- Current Git repository URL, if any
    
      -- Editor Information
      is_focused        = boolean,          -- Whether Neovim is focused
      is_idle           = boolean,          -- Whether the session is idle
      buttons           = table?,           -- List of configured presence buttons
    
      -- Asset Information
      type              = string,           -- Which category the asset belongs to, e.g. 'language' or 'docs'
      icon              = string?,          -- Asset icon URL or name, if any
      text              = string?,          -- Custom text to display, if any
    }
<

The `ActivityManager` contains useful methods:


ACTIVITYMANAGER METHODS           *cord-configuration-activitymanager-methods*

  ------------------------------------------------------------------------------------------
  Method                               Description
  ------------------------------------ -----------------------------------------------------
  manager:queue_update(force_update)   Schedules an update to the activity. If force_update
                                       is true, it bypasses checks and updates immediately.

  manager:pause()                      Pauses all events and stops the idle timer.

  manager:resume()                     Resumes events and restarts the idle timer.

  manager:pause_events()               Disables event handling without affecting the idle
                                       timer.

  manager:resume_events()              Enables event handling and queues an immediate
                                       update.

  manager:skip_update()                Skips the next update once.

  manager:hide()                       Pauses events and clears rich presence.

  manager:suppress()                   Pauses events and suppresses sending presence updates
                                       for the current Neovim session.

  manager:toggle()                     Toggles between pausing and resuming the activity
                                       updates.

  manager:toggle_suppress()            Toggles between suppressing and resuming sending
                                       presence updates for the current Neovim session.

  manager:idle()                       Sets the session to idle.

  manager:force_idle()                 Forcibly sets the session to idle until unforced.

  manager:unidle()                     Clears the idle state and resumes normal activity.

  manager:toggle_idle()                Toggles between idle and normal activity.

  manager:set_activity(activity)       Sets the rich presence to the provided activity,
                                       offering complete control over the presence.

  manager:clear_activity(force)        Clears the current activity from the server. If force
                                       is true, it completely clears the presence.
  ------------------------------------------------------------------------------------------

ACTIVITY OPTIONS                         *cord-configuration-activity-options*

  ---------------------------------------------------------------------------------
  Parameter    Type      Description
  ------------ --------- ----------------------------------------------------------
  type         number    One of ‘playing’, ‘listening’, ‘watching’

  state        string    The user’s current state (e.g., “Editing a file”).

  details      string    Detailed information about what the user is doing.

  timestamps   table     Contains start and end timestamps for the activity.

  assets       table     Defines images and tooltips, including large_image,
                         large_text, small_image, and small_text.

  buttons      array     Array of objects, each with label and url, defining
                         interactive buttons in the presence.

  is_idle      boolean   Whether the activity should be considered as idle.
  ---------------------------------------------------------------------------------

USEFUL FUNCTIONS                         *cord-configuration-useful-functions*

- `require('cord.api.icon').get(name: string, theme?: string, flavor?: string): string`
    - **Get Icon URL:** Returns the URL for the specified icon `name`, optional `theme`, and optional `flavor`. If `theme` or `flavor` is not provided, they default to the configured `display.theme` and `display.flavor`, respectively. Useful for referencing Cord’s built-in icons in your custom configurations.


==============================================================================
2. Custom Assets                                          *cord-custom-assets*

Cord allows you to go beyond the default icons and fully customize the assets
used in your Discord Rich Presence. This guide will walk you through how to
define and configure custom assets to perfectly match your workflow and style.


STRUCTURE                                       *cord-custom-assets-structure*

Custom assets are configured within the `assets` table in your `cord.setup()`
call. The basic structure is as follows:

>lua
    require('cord').setup {
      assets = {
        -- "key" = "icon" or { asset_options }
      },
    }
<

Here, `"key"` is the identifier for the asset, and `"value"` can be either a
simple string for the asset icon or a table for more detailed asset options.


ASSET KEYS                                     *cord-custom-assets-asset-keys*

The `key` in your asset configuration determines what type of file or context
the custom asset will apply to. You can use the following key types:

- **Filetype**Use a Vim filetype string (e.g., `"lua"`, `"python"`) to set assets for specific languages.
- **Filename**Use a specific filename (e.g., `"Cargo.toml"`, `"README.md"`) to customize assets for particular files.
- **File Extension**Use a file extension (e.g., `".rs"`, `".js"`) to apply assets to all files with that extension.
- **Special Keys**Cord provides special keys for generic scenarios (see |cord-overriding-defaults|).


ASSET OPTIONS                               *cord-custom-assets-asset-options*

When you use a table as the `value` in your asset configuration, you can
specify these options to fine-tune your custom asset:

  ---------------------------------------------------------------------------------------
  Option    Type                 Description
  --------- -------------------- --------------------------------------------------------
  icon      string \| function   A direct URL to the icon image or the name of a rich
                                 presence asset (if using your own Discord application).

  tooltip   string \| function   Text that appears when you hover over the icon in
                                 Discord.

  name      string \| function   An optional override for the icon’s name. Generally used
                                 for types other than language.

  text      string \| function   An optional override for the icon’s text. Completely
                                 replaces the default text.

  type      string               Specifies the context of the asset. See Asset Types for
                                 available options.
  ---------------------------------------------------------------------------------------

ASSET TYPES ~

The `type` option categorizes your asset, influencing how Cord displays it.
Available types include: - `language` (default) - `docs` - `plugin_manager` -
`lsp_manager` - `file_browser` - `vcs` - `workspace` - `dashboard` - `notes` -
`debug` - `test` - `diagnostics` - `games` - `terminal`


EXAMPLES                                         *cord-custom-assets-examples*

**1. Simple Icon Replacement by Extension:**

>lua
    assets = {
      ['.rs'] = 'https://...', -- Use this icon URL for all Rust files
    }
<

This will use the given icon URL for any file with the `.rs` extension.

**2. Custom Icon and Tooltip for a Filetype:**

>lua
    assets = {
      lua = {
        icon = 'lua_custom_icon',
        tooltip = 'Lua Script', -- Custom tooltip for Lua files
      },
    }
<

This example sets a custom icon and tooltip specifically for Lua files (the
`lua` filetype).

**3. Using Cord’s Built-in Icons:**

>lua
    assets = {
      ['.settings'] = require('cord.api.icon').get('settings'),
    }
<

This makes use of Cord’s default icon library, using the "settings" icon for
files with the `.settings` extension.

**4. Plugin Manager Asset with Custom Text:**

>lua
    assets = {
      lazy = {
        name = 'Lazy',
        icon = 'https://...',
        tooltip = 'lazy.nvim Plugin Manager',
        type = 'plugin_manager',
        text = function(opts) -- Dynamic text
          return 'Managing plugins in ' .. opts.name
        end,
      },
    }
<

Here, we define a custom asset for the `lazy.nvim` plugin manager, setting its
name, icon, tooltip, type, and dynamic text.

**5. Overriding Tooltip and Text, Keeping Default Icon:**

>lua
    assets = {
      lua = {
        tooltip = '.lua file',     -- Just change the tooltip
        text = 'Writing Lua Code', -- Override the text
      },
    }
<

This example only modifies the tooltip and text for Lua files, keeping Cord’s
default icon.


OVERRIDING DEFAULTS                   *cord-custom-assets-overriding-defaults*

Cord provides special keys to define assets for generic situations:

- `['Cord.new']`Asset for a new, empty buffer when Neovim starts without file arguments, when both filetype and filename are empty.
- `['Cord.unknown']`Asset when the filetype is not detected/defined in Cord.
- `['Cord.override']`This key overrides _all_ existing icons, applying the specified asset everywhere.

**Example of Default Overrides:**

>lua
    assets = {
      ['Cord.new'] = 'default_file_icon',
      ['Cord.unknown'] = 'question_mark_icon',
      ['Cord.override'] = 'my_brand_icon',
    }
<


TIP                                                   *cord-custom-assets-tip*

Sometimes, filetypes aren’t automatically recognized by Neovim based on
filename or extension alone. Use `vim.filetype.add` to help the editor identify
them:

>lua
    vim.filetype.add {
      pattern = {
        ['.*/waybar/config'] = 'jsonc',    -- Recognize waybar config files as jsonc
        ['.*/hypr/.*%.conf'] = 'hyprlang', -- Hyprland configs as hyprlang
        -- ... add more custom patterns
      },
    }
<


==============================================================================
3. Plugins                                                      *cord-plugins*

Cord comes with several built-in plugins that you can easily enable and
configure to enhance your Discord Rich Presence right away. These plugins
provide ready-made functionality for common use cases.


ENABLING PLUGINS                               *cord-plugins-enabling-plugins*

To use a built-in plugin, simply add its `require` path to the `plugins` table
in your `cord.setup()` configuration.

**Basic Plugin Enablement:**

>lua
    require('cord').setup {
      plugins = {
        'cord.plugins.diagnostics', -- Enable the diagnostics plugin
      },
    }
<

**Enabling and Configuring a Plugin:**

If a plugin has configuration options, you can provide a configuration table
using the plugin’s require path as the key in the `plugins` table.

>lua
    require('cord').setup {
      plugins = {
        'cord.plugins.diagnostics', -- Enable diagnostics plugin with default settings
    
        ['cord.plugins.diagnostics'] = { -- Configure diagnostics plugin
          scope = 'workspace', -- Set scope to 'workspace' instead of default 'buffer'
          severity = vim.diagnostic.severity.WARN, -- Show warnings and above
        },
      },
    }
<


AVAILABLE PLUGINS                             *cord-plugins-available-plugins*

Here’s a list of the built-in plugins included with Cord, along with their
descriptions and configuration options:


DIAGNOSTICS (CORD.PLUGINS.DIAGNOSTICS) ~

**Purpose:** Adds real-time LSP diagnostics (errors, warnings, hints)
information to your Rich Presence. Displays the number of diagnostics in the
current buffer or workspace.

**Configuration Options:**

>lua
    {
      scope = 'buffer',      -- 'buffer' (default) or 'workspace': Scope of diagnostics to display
      severity = { min = vim.diagnostic.severity.WARN }, -- Diagnostic severity filter (see Neovim `:help diagnostic-severity`)
      override = true,     -- Whether to override default text configurations (recommended: true)
    }
<

- **scope**
    - `'buffer'`(default): Show diagnostics count for the _current buffer_ only. Overrides `text.viewing` and `text.editing` to include diagnostics count.
    - `'workspace'`Show diagnostics count for _all buffers in the workspace_. Overrides `text.workspace` to include diagnostics count.
- **severity**
    - Atable defining the minimum diagnostic severity level to include in the count. Uses Neovim’s diagnostic severity levels (see `:help diagnostic-severity`).
    - Example: `{ min = vim.diagnostic.severity.WARN }` will count warnings and errors, but not information messages or hints.
    - Defaults to showing errors.
- **override**
    - `true`(default): The plugin will automatically override the `text.viewing`, `text.editing`, and `text.workspace` options to display diagnostics information. Recommended for seamless integration.
    - `false`The plugin will _not_ override text options. You’ll need to manually use the plugin’s variables in your `text` configuration to display diagnostics (see "Usage Example" below).

**Variables Added:**

- **diagnostic**A table containing the scoped diagnostics data (useful for advanced customization).
- **diagnostics**A function that returns the number of diagnostics in the current scope (buffer or workspace), based on the plugin’s configuration.

**Usage Example (Manual Text Configuration - override = false):**

>lua
    text = {
      -- In string templates
      editing = 'Editing ${filename} - ${diagnostics} problems',
    
      -- In functions
      workspace = function(opts) return 'In ' .. opts.workspace .. ' - ' .. opts.diagnostics(opts) .. ' problems' end,
    }
<


LOCAL TIME (CORD.PLUGINS.LOCAL_TIME) ~

**Purpose:** Sets the Rich Presence timestamp to display the current local
clock time (hours, minutes and seconds) instead of elapsed time.

**Configuration Options:**

>lua
    {
      affect_idle = true,
    }
<

- **affect_idle**
    - `true`(default): Also sets the timestamp for the idle status to local time.
    - `false`Only affects the timestamp for active presence, elapsed time will be shown when idle.

**Variables Added:**

- **local_timestamp**A function that returns the zeroed timestamp of the current local time (midnight of the current day).


  [!NOTE] Incompatible with `cord.plugins.local_time`

SCOPED TIMESTAMPS (CORD.PLUGINS.SCOPED_TIMESTAMPS) ~

**Purpose:** Tracks elapsed time independently for each buffer or workspace.
Optionally "pauses" and "resumes" the timestamp when switching between buffers,
providing more context-aware time tracking.

**Configuration Options:**

>lua
    {
      scope = 'buffer', -- 'buffer' (default), 'workspace', or 'idle'
      pause = true,
    }
<

- **scope**
    - `'buffer'`(default): Track time elapsed _per buffer_. Timestamp resets when switching buffers (if `pause = false`), or pauses/resumes (if `pause = true`).
    - `'workspace'`Track time elapsed _per workspace_. Timestamp is consistent across buffers within the same workspace.
    - `'idle'`Track time spent in _idle state_. Shows elapsed idle time when in idle, and normal activity time when active.
- **pause**
    - `true`(default): When switching scope, the timestamp "pauses" for the previous scope and "resumes" where it left off when you return to that scope.
    - `false`When switching scope, the timestamp for the previous scope is not untouched, resulting in two scopes.

**Variables Added:**

- **get_scoped_timestamp()**A function that returns the appropriate timestamp value based on the plugin’s `scope` and `pause` settings. This is used internally by the plugin.


  [!NOTE] Incompatible with `cord.plugins.local_time`

==============================================================================
4. Examples                                                    *cord-examples*

Learn how to customize your Discord presence in countless ways using Cord’s
robust configuration system. The possibilities are endless, and the only limit
is your creativity!


CUSTOMIZING ICONS ~


  [!IMPORTANT] If you use a plugin manager, avoid using `require` directly in
  tables; instead, use them within function initializers.
>lua
    opts = function()
      return {
        display = {
          theme = 'default',
          flavor = 'dark',
        },
        lazy = {
          -- change default idle icon to keyboard
          icon = require('cord.api.icon').get('keyboard'),
          -- or use another theme's idle icon
          icon = require('cord.api.icon').get('idle', 'atom'),
          -- or use another theme's idle icon from a different flavor
          icon = require('cord.api.icon').get('idle', 'atom', 'light'),
        }
      }
    end
<


CURSOR POSITION ~

>lua
    text = {
      editing = function(opts)
        return string.format('Editing %s - %s:%s', opts.filename, opts.cursor_line, opts.cursor_char)
      end
    }
<


OMITTING FIELDS ~

>lua
    text = {
      workspace = '',
      -- or
      workspace = function() end,
      -- or
      workspace = function() return '' end
    }
<


LOCAL TIME AS TIMESTAMP ~

>lua
    hooks = {
      on_activity = function(opts, activity)
        local date = os.date('*t')
        date.hour, date.min, date.sec = 0, 0, 0
        activity.timestamps.start = os.time(date)
      end,
    
      -- optionally, you can do one of the two:
      -- A. also set local time for idle status, or
      on_idle = function(opts, activity)
        local date = os.date('*t')
        date.hour, date.min, date.sec = 0, 0, 0
        activity.timestamps.start = os.time(date)
      end
    }
    
    -- B. reset the timestamp for idle activity, regular activity is not affected in this case
    timestamp = {
      reset_on_idle = true
    }
<


WORKSPACE BLACKLIST ~

>lua
    local blacklist = {
      'blacklisted_workspace',
      'another_blacklisted_workspace'
    }
    
    local is_blacklisted = function(opts)
      return vim.tbl_contains(blacklist, opts.workspace)
    end
    
    -- use a custom text for the activity
    text = {
      viewing = function(opts)
        return is_blacklisted(opts) and 'Viewing a file' or ('Viewing ' .. opts.filename)
      end,
      editing = function(opts)
        return is_blacklisted(opts) and 'Editing a file' or ('Editing ' .. opts.filename)
      end,
      workspace = function(opts)
        return is_blacklisted(opts) and 'In a secret workspace' or ('Working on ' .. opts.workspace)
      end
    }
    
    -- or simply hide the activity when in a blacklisted workspace
    hooks = {
      workspace_change = function(opts)
        if is_blacklisted(opts) then
          opts.manager:hide()
        else 
          opts.manager:resume()
        end
      end
    }
<


GIT BRANCH & STATUS ~

>lua
    local git_branch = vim.fn.system('git branch --show-current'):gsub('\n', '')
    
    variables = {
      git_status = function(opts)
        return git_branch
      end
    }
    
    text = {
      editing = function(opts)
        return string.format('Editing %s - on branch %s', opts.filename, opts.git_status)
      end
    }
    
    hooks = {
      workspace_change = function(opts)
        git_branch = vim.fn.system('git branch --show-current'):gsub('\n', '')
      end
    }
<


TIME-BASED STATUS ~

>lua
    text = {
      workspace = function(opts)
        local hour = tonumber(os.date('%H'))
        local status = 
          hour >= 22 and '🌙 Late night coding' or
          hour >= 18 and '🌆 Evening session' or
          hour >= 12 and '☀️ Afternoon coding' or
          hour >= 5 and '🌅 Morning productivity' or
          '🌙 Midnight hacking'
        
        return string.format('%s: %s', status, opts.filename)
      end
    }
<


LSP-AWARE STATUS ~

>lua
    local get_errors = function(bufnr) return vim.diagnostic.get(bufnr, { severity = vim.diagnostic.severity.ERROR }) end
    local errors = get_errors(0) -- pass the current buffer; pass nil to get errors for all buffers
    
    vim.api.nvim_create_autocmd('DiagnosticChanged', {
      callback = function()
        errors = get_errors(0)
      end
    })
    
    text = {
      editing = function(opts)
        return string.format('Editing %s - %s errors', opts.filename, #errors)
      end
    }
<


  [!NOTE] Consider using the built-in diagnostics plugin
  <./Plugins.md#diagnostics-cordpluginsdiagnostics>.

DYNAMIC BUTTONS ~

>lua
    buttons = {
      {
        label = function(opts)
          return opts.repo_url and 'View Repository' or 'My Website'
        end
        url = function(opts)
          return opts.repo_url or 'https://example.com'
        end
      }
    }
<


DOCUMENTATION LINKS ~

>lua
    buttons = {
      {
        label = function(opts)
          local docs = {
            rust = 'Rust Docs',
            typescript = "TS Docs',
            lua = 'Lua Reference',
          }
          return docs[opts.filetype] or 'Documentation'
        end,
        url = function(opts)
          local urls = {
            rust = 'https://doc.rust-lang.org/std/',
            typescript = 'https://www.typescriptlang.org/docs/',
            lua = 'https://www.lua.org/manual/5.1/',
          }
          return urls[opts.filetype] or 'https://devdocs.io'
        end
      }
    }
<


PROJECT-BASED IDLE MESSAGES ~

>lua
    idle = {
      details = function(opts)
        return string.format('Taking a break from %s', opts.workspace)
      end
    }
<


HIDE BUTTONS ON IDLE ~

>lua
    buttons = {
      {
        label = 'View Repository',
        url = function(opts)
          if not opts.is_idle then return opts.repo_url end
        end
      }
    }
<


INDICATE MODIFIED BUFFERS ~

>lua
    text = {
      editing = function(opts)
        local text = 'Editing ' .. opts.filename
        if vim.bo.modified then text = text .. '[+]' end
        return text
      end,
    }
<


RANDOM QUOTES ~

>lua
    local quotes = {
      'GTA VI came out before my Rust program finished compiling. ⏳',
      'When your code works on the first try. 😱',
      'It’s not a bug, it’s a feature. 🐛✨',
      'I don’t always test my code, but when I do, I do it in production. 💥',
      'My code works, I have no idea why. 🤷‍♂️',
      'Hello from the other side... of a merge conflict. 🔀',
      'If it works, don’t touch it. 🛑',
      'May your code never compile on the first try. 🤞',
    }
    
    hooks = {
      post_activity = function(_, activity)
        activity.details = quotes[math.random(#quotes)]
      end
    }
<


LAST.FM INTEGRATION ~

>lua
    local user, api_key, song = 'YOUR_USERNAME', 'YOUR_API_KEY'
    local timer = vim.uv.new_timer()
    timer:start(
      0,
      15000, -- look for new song every 15 seconds (default ratelimit on most Discord clients)
      vim.schedule_wrap(function()
        vim.system(
          { 'curl', 'http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=' .. user .. '&api_key=' .. api_key .. '&format=json&limit=1, '-s', '--fail' },
          { text = true },
          vim.schedule_wrap(function(opts)
            if opts.code ~= 0 or not opts.stdout then
              print 'Failed to fetch data from last.fm'
              timer:close()
              return
            end
    
            local data = vim.fn.json_decode(opts.stdout)
            local recenttracks = data.recenttracks
            if not recenttracks then
              print 'Failed to fetch recenttracks from last.fm'
              timer:close()
              return
            end
    
            local track = recenttracks.track[1]
            if not track or not track['@attr'] then
              song = nil
              return
            end
    
            song = track.name
            if song == '' then song = nil end
          end)
        )
      end)
    )
    
    return {
      text = {
        workspace = function(opts)
          if song then return ('🎶 Playing ' .. song) end
          return opts.workspace
        end,
      },
    }
<


KEYMAPPINGS ~

>lua
    vim.keymap.set('n', '<leader>Ct', function() require('cord.api.command').toggle_presence() end)
    vim.keymap.set('n', '<leader>Ci', function() require('cord.api.command').toggle_idle_force() end)
<




  [!IMPORTANT] Cord no longer requires Rust to be installed. Rust component will
  be automatically downloaded from GitHub Releases.

FEATURES                                              *cord-examples-features*

- **Client-Server Design** — Handles multiple Neovim instances with a single connection to Discord.
- **Performance in Mind** — Lightweight, dependency-free, with blazingly-fast startup.
- **Event-Driven Architecture** — Instant presence updates with zero delays.
- **Customizable Templates** — Dynamic string templates with custom variables.
- **Unmatched Configurability** — Function-based configuration for infinite customization possibilities.
- **Automated State Handling** — Automatically manages activities across all instances.
- **Smart Idle Detection** — Identifies idle sessions and switches to the most recent non-idle session.
- **Built-in Git Integration** — Detects repositories and workspaces based on VCS files without relying on command-line tools.
- **Custom Assets** — Extendable with fully customizable assets for any file/buffer type.
- **Robust User Commands** - Quickly manage Cord and its features through user commands and easily create your own keybindings.
- **Plugin System** — Extendable with custom plugins, with a plethora of built-in ones out of the box.
- **Wide Compatibility** - Compatible with various Discord installations (Snap, Flatpak) and able to work inside WSL <https://github.com/vyfor/cord.nvim/wiki/Troubleshooting#running-inside-wsl> and Discord in browser <https://github.com/vyfor/cord.nvim/wiki/Troubleshooting#using-discord-in-browser>.
- **Cross-Platform** — Supports Windows, Linux, macOS, and FreeBSD.
- **Rich Icon Collection** — Features 120+ uniquely designed themed icons for 200+ file types and plugins.
- **Automatic Reconnection** — Able to reconnect to Discord if the connection is lost.


QUICK START                                        *cord-examples-quick-start*

For most users, the quickest way to get started is using **lazy.nvim**

>lua
    {
      'vyfor/cord.nvim',
      build = ':Cord update',
      -- opts = {}
    }
<


CONSIDERATIONS ~

Expand ~

Cordrequires the server executables to be present. To get it, you can either: -
**Fetch from GitHub**Invoking `:Cord update [fetch]` (async, recommended). Make
sure you have **curl** installed. - **Download from GitHub**Get latest release
from https://github.com/vyfor/cord.nvim/releases/latest, rename it to
cord[.exe] and place it under `nvim-data-dir/cord/bin` -
|cord-**build-from-source**|


INSTALLATION ~

Using packer.nvim ~

>lua
    use {
      'vyfor/cord.nvim',
      run = ':Cord update',
      -- config = function()
      --   require('cord').setup {}
      -- end
    }
<

Using rocks.nvim ~

Cord is available on LuaRocks <https://luarocks.org/modules/vyfor/cord.nvim>.

>vim
    :Rocks install cord.nvim
<

Invoke `:Cord update` whenever the plugin is updated.

Using Vim packages ~

**Unix:**

>bash
    git clone https://github.com/vyfor/cord.nvim ~/.local/share/nvim/site/pack/plugins/start/cord.nvim
<

**Windows:**

>powershell
    git clone https://github.com/vyfor/cord.nvim $LOCALAPPDATA/nvim-data/site/pack/plugins/start/cord.nvim
<

Invoke `:Cord update` whenever the plugin is updated.

Other ~

Invoke `:Cord update` whenever the plugin is updated.


THEMES                                                  *cord-examples-themes*

Cord boasts over 120 meticulously crafted icons for languages and tools,
available in distinct themes to match your style.

**Explore the Icon Showcase**vyfor/icons
<https://github.com/vyfor/icons#showcase>

Cord currently offers three themes:

- **Default**A clean and stylish theme featuring widely recognized icons.
- **Atom**A sleek theme inspired by Atom Material Icons
- **Catppuccin**A soothing pastel theme inspired by Catppuccin.

Each theme includes multiple flavors, typically `dark`, `light`, and `accent`.

Choose your theme in the `display` configuration option. More themes are coming
soon!


DOCUMENTATION                                    *cord-examples-documentation*

Dive deeper into Cord’s features and customization options in the **Wiki**
<https://github.com/vyfor/cord.nvim/wiki>

- **Configuration Guide**Master all the settings to tailor Cord to your exact needs.
- **Examples**Get inspired with creative ways to customize your Discord presence.
- **Migration Guide**Upgrade smoothly from Cord v1.
- **FAQ**Frequently asked questions about Cord.
- **Troubleshooting Guide**Find solutions to common issues and scenarios.


VERSIONING                                          *cord-examples-versioning*

We follow a **modified versioning specification**

- **PATCH**Non-breaking changes.
- **MINOR**Breaking changes.
- **MAJOR**Significant rewrites or fundamental shifts, bumped manually.

All breaking changes will be **announced in GitHub Discussions**.


CONTRIBUTING                                      *cord-examples-contributing*

We welcome contributions to make Cord even better! - Check out our
**Contribution Guidelines**
<https://github.com/vyfor/cord.nvim/wiki/Contributing>.


SUPPORT THE PROJECT                        *cord-examples-support-the-project*

I’m the sole maintainer of cord.nvim and dedicate much of my free time to
this project. If you find Cord helpful, you can show your support by giving the
repo a star or sponsoring me on GitHub <https://github.com/sponsors/vyfor>.
Every bit of support helps me continue to improve and maintain Cord for
everyone. Thank you!


BUILD FROM SOURCE                            *cord-examples-build-from-source*


  [!NOTE] Make sure you have **Rust** >= 1.85.0 installed.
To build Cord from source, you can run `:Cord update build` (async) which will
install the server binary from crates.io by running the following command:

>bash
    cargo install --path . --root path/to/nvim-data-dir/cord --force
<

Alternatively, you can use `cargo b --release` to build the binary, then place
it under `nvim-data-dir/cord/bin`.

------------------------------------------------------------------------------

Generated by panvimdoc <https://github.com/kdheepak/panvimdoc>

vim:tw=78:ts=8:noet:ft=help:norl:
