Fixed some thinks that seemed to have gotten broken after unrecording the WIP change, that worked before I unrecorded it and had fixed it. Though gui seems to not work now, but it does compile.

Wallby
Feb 18, 2026, 5:11 PM
AGC2PCBAGGYLAU7P44APFYPZ66RULCZJJ7UZAFZNL4OFVZJDKN2AC

Dependencies

  • [2] NSE6BLWA init slint project from https://github.com/slint-ui/slint-rust-template
  • [3] 4RPYR65C connect GUI to pijul to display simple channel list
  • [4] IQY5LHEN add GUI element to display simple `pijul log` results
  • [5] G2CHQAOP parsed `pijul log` text blob into individual entries & fields
  • [6] 6ECOC7L5 parsed `pijul channel` text blob into individual UI components
  • [7] 6M4YFQEB added command-line argument to specify repository path
  • [8] ZGSCV5DI split channel labels into discrete component
  • [9] SOTD66FO set Changelog UI to display log from selected channel in ChannelsList UI
  • [10] F6YAQWVD added UI for `pijul change`
  • [11] BD456SZF added diff view
  • [12] 3W2E3DX2 added counter for pending diff files
  • [13] V3SZ2LL2 refactored UI update logic into discrete functions
  • [14] 6G2N6O4C refactored channels data into `ChannelsData` struct
  • [15] 24AA2GFB Fork from https://nest.pijul.com/CrepeGoat/pijul-gui, though it was in a broken state. Is this RepoCommander which seems to have been taken down https://discourse.pijul.org/t/repocommander-first-gui-for-pijul-help-volunteers-needed/1095?
  • [16] RT22YHJF change spacing of active channel indicator for aesthetics
  • [17] 337EO2TU add selection callback to changelog UI (& fix deselection)
  • [18] M5HBKVCE add selection callback to channel list UI (& fix deselect)
  • [19] XERTHGSY consolidated `pijul log` UI elements into their own component
  • [20] PL4TK55O added command-line argument to specify executable path
  • [*] NCRTU7M4 cargo init

Change contents

  • edit in ui/app-window.slint at line 154
    [15.99][15.99:297]()
    component ChannelsList {
    in-out property <[string]> channels;
    in-out property <int> active;
    VerticalBox {
    alignment: start;
    spacing: 0;
    preferred-width: 150px;
  • edit in ui/app-window.slint at line 155
    [15.298][15.298:416](),[15.416][8.0:19](),[5.872][8.0:19]()
    Text {
    text: "channels";
    for ch in channels: Text {
    text: "\{ch}";
    }
    }
    }
    }
  • replacement in ui/app-window.slint at line 198
    [6.96][15.417:446]()
    component ChannelsListView {
    [6.96]
    [14.71]
    component ChannelsList {
  • edit in ui/app-window.slint at line 233
    [2.161][15.447:562]()
    in-out property <[string]> channels <=> chs.channels;
    in-out property <int> active-channel <=> chs.active;
  • edit in ui/app-window.slint at line 243
    [9.42][10.575:618](),[10.618][12.260:303](),[12.303][11.996:1038](),[10.618][11.996:1038](),[11.1038][13.0:144](),[13.144][14.276:405](),[14.405][13.207:246](),[12.367][13.207:246](),[13.246][11.1070:1142](),[12.367][11.1070:1142](),[11.1070][11.1070:1142](),[11.1212][11.1212:1229](),[14.472][11.1293:1309](),[11.1293][11.1293:1309]()
    callback request-change-delta(string);
    callback request-diff-summary(string);
    callback request-diff-delta(string);
    function fill-chs() {
    chs.deselect();
    root.request-channel-list();
    }
    function fill-log() {
    log.deselect();
    root.request-changes-log(chs.data.names[chs.selected]);
    root.request-diff-summary(chs.data.names[chs.selected]);
    }
    function fill-diff-view() {
    if log.selected >= 0 && log.selected < log.changes_log.length {
    } else {
    }
    }
  • replacement in ui/app-window.slint at line 256
    [4.363][15.563:756]()
    //chs := ChannelsList {
    // channels: [];
    // active: 0;
    // preferred-width: 500px;
    //}
    chs := ChannelsListView {
    [4.363]
    [10.812]
    chs := ChannelsList {
  • edit in ui/app-window.slint at line 276
    [2.484]
    [15.757]
    callback request-changes-log(string);
    callback request-change-delta(string);
    callback request-diff-summary(string);
    callback request-diff-delta(string);
    function fill-chs() {
    chs.deselect();
    root.request-channel-list();
    }
    function fill-log() {
    log.deselect();
    root.request-changes-log(chs.data.names[chs.selected]);
    root.request-diff-summary(chs.data.names[chs.selected]);
    }
    function fill-diff-view() {
    if log.selected >= 0 && log.selected < log.changes_log.length {
    root.request-change-delta(changes_log[log.selected].hash)
    } else {
    root.request-diff-delta(chs.data.names[chs.selected])
    }
    }
  • edit in src/main.rs at line 48
    [6.1298][15.759:1078]()
    ui.set_channels((&channel_strs[..]).into());
    ui.set_active_channel(i32::try_from(channel_list.active).unwrap_or(-1));
    let channel_strs = channel_list
    .entries
    .into_iter()
    .map(SharedString::from)
    .collect::<Vec<_>>();
  • replacement in src/main.rs at line 206
    [7.1377][15.1079:1080]()
    }
    [7.1377]
    }
  • edit in src/cmds.rs at line 4
    [3.979][15.1081:1176]()
    pub fn channel(exe: &std::path::Path, repo: &std::path::Path) -> Result<ChannelsList, Error> {
  • edit in src/cmds.rs at line 13
    [4.1800][15.1177:1839]()
    parse_channel_output(output.stdout)
    }
    fn parse_channel_output(output: Vec<u8>) -> Result<ChannelsList, Error> {
    let channels_str = String::from_utf8(output)?;
    let channels_list = channels_str.split('\n').map(|substr| substr.trim()).fold(
    ChannelsList::new(),
    |mut channels_list, ch_str| {
    if ch_str.starts_with("* ") {
    channels_list.active = channels_list.entries.len();
    channels_list.entries.push(ch_str[2..].to_string());
    } else {
    channels_list.entries.push(ch_str.to_string());
    }
    channels_list
    },
    );
    Ok(channels_list)
  • edit in src/cmds.rs at line 137
    [6.2202][15.1840:1953]()
    #[derive(Debug)]
    pub struct ChannelsList {
    pub(crate) entries: Vec<String>,
    pub(crate) active: usize,
    }
  • edit in src/cmds.rs at line 144
    [6.2313][15.1954:2107]()
    }
    impl ChannelsList {
    pub(crate) fn new() -> Self {
    Self {
    entries: Vec::new(),
    active: usize::MAX,
    }
    }
  • replacement in src/cmds.rs at line 161
    [5.2277][15.2108:2109]()
    }
    [5.2277]
    }