hexchat-api 0.2.2

A Rust API for HexChat plugin development
Documentation
hexchat-api-0.2.2 has been yanked.

Rust Hexchat API

This library provides a Rust API to the Hexchat Plugin Interface with additional Rust friendly features such as:

  • A thread-safe API.
  • Simple user_data objects.
  • Abstractions like Context that make it simple to interact with specific tabs/windows in the UI.
  • Panic's are caught and displayed in the active Hexchat window.
  • Debug builds include a full stack trace for panics.
  • Hooked commands can be implemented as normal functions or closures.
  • Typed preference values and easy plugin pref access.

Documentation

Documentation can be found here

Examples

A completed plugin offers the most examples to pull from. Here's a plugin that does automatic translations which enables chatting with people in different tongues (chat with subtitles).

Setting up and registering commands using the API is easy and syntactically clean.

Interaction between threads and Hexchat is facilitated by main_thread(), which uses Hexchat's timer event loop to delegate tasks, such as printing output to the active Hexchat window.

hexchat.hook_command(
    "runthread",
    Priority::Norm,

    |hc, word, word_eol, ud| {
        // Spawn a new thread.
        thread::spawn(|| {
            // Send a task to the main thread to have executed and get its
            // AsyncResult object.
            let async_result = main_thread(
                                    |hc| {
                                        hc.print("Hello from main thread!");
                                        "This is the return value from main!"
                                    });
            // Get the return data from the main thread callback (blocks).
            let result = async_result.get();
            hc_print_th!("Spawned thread received from main thread: {}", 
                         result);
        });
        Eat::All
    },

    "Runs a new thread that sets up a closure to run on the main thread.",
    NoData);

Linking to hexchat_api

Simply include an entry in your Rust project's Cargo.toml file:

[dependencies]

hexchat-api = "0.2"

Template

The code below can be copied to start a new plugin project. The TOML file content is also included below.

// FILE: lib.rs

//! A starter project template that can be copied and modified.

use hexchat_api::*;
use UserData::*;

// Register the entry points of the plugin.
//
dll_entry_points!(plugin_info, plugin_init, plugin_deinit);

/// Called when the plugin is loaded to register it with Hexchat.
///
fn plugin_info() -> PluginInfo {
    PluginInfo::new(
        "Plugin Template",
        "0.1",
        "A Hexchat plugin to customize.")
}

/// Called when the plugin is loaded.
///
fn plugin_init(hc: &Hexchat) -> i32 {
    hc.print("Plugin template loaded");
   
    // Example user data to pass to a callback.
    let udata = UserData::boxed("Some data to pass to a callback.");
    
    // Register a simple command using a function.
    hc.hook_command("HELLOWORLD", 
                    Priority::Norm, 
                    hello_world, 
                    "Prints \"Hello, world!\"", 
                    NoData);

    // Register a simple command using a closure.
    hc.hook_command("HELLOHEX", 
                    Priority::Norm, 
                    |hc, word, word_eol, user_data| {
                    
                        hc.print("Hello, Hexchat!");
    
                        user_data.apply(|msg: &&str| { hc.print(msg); });
    
                        Eat::All
                    }, 
                    "Prints \"Hello, Hexchat!\", and the user data.", 
                    udata);
    1
}

/// Called when the plugin is unloaded.
///
fn plugin_deinit(hc: &Hexchat) -> i32 {
    hc.print("Plugin template unloaded");
    1
}

/// A command callback implemented as a function.
/// # Arguments
/// * `hc`        - The Hexchat API object reference.
/// * `word`      - A list of parameters passed to the command.
/// * `word_eol`  - Like `word`, but catenates the word args decrementally.
/// * `user_data` - The user data to be passed back to the command when invoked
///                 by Hexchat.
/// # Returns
/// * One of `Eat::All`, `Eat::Hexchat`, `Eat::Plugin`, `Eat::None`. 
///
fn hello_world(hc        : &Hexchat, 
               word      : &[String], 
               word_eol  : &[String], 
               user_data : &UserData
              ) -> Eat
{
    hc.print("Hello, world!");
    Eat::All
}

And the Cargo.toml file.

[package]

name = "hexchat_plugin_template"

version = "0.1.0"

authors = ["you <your@email.com>"]

edition = "2021"



[lib]

name = "hexchat_plugin_template"

crate-type = ["cdylib"]



[dependencies]

hexchat-api = "0.2"