') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Add a sort option popup to branch list view by UUGTech · Pull Request #2146 · gitui-org/gitui · GitHub
Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f763407
add BranchSortPopup
UUGTech Mar 22, 2024
9d3d664
fix height of branch sort popup
UUGTech Mar 22, 2024
2d0ca22
small fix
UUGTech Mar 22, 2024
c893ff7
fix clippy
UUGTech Mar 22, 2024
7ce8e27
fix unless use of vec!
UUGTech Mar 22, 2024
5c02b3c
rebase
UUGTech Mar 25, 2024
dec6128
change sort key with navigation keys
UUGTech Mar 25, 2024
a39bc4c
remove unused keybindings
UUGTech Mar 25, 2024
d329b95
fix to use capital X
UUGTech Mar 25, 2024
c56227f
add BranchSortPopup
UUGTech Mar 22, 2024
d2a4c8f
fix height of branch sort popup
UUGTech Mar 22, 2024
0271e5b
small fix
UUGTech Mar 22, 2024
bed46c8
fix clippy
UUGTech Mar 22, 2024
4443faf
fix unless use of vec!
UUGTech Mar 22, 2024
ae31456
rebase
UUGTech Mar 25, 2024
5a6a679
change sort key with navigation keys
UUGTech Mar 25, 2024
2806894
remove unused keybindings
UUGTech Mar 25, 2024
0c1c973
fix to use capital X
UUGTech Mar 25, 2024
cec6a9e
Merge branch 'master' into feat-sort-branch
extrawurst Apr 3, 2024
0848790
avoid unwrap()
UUGTech Apr 14, 2024
c87ee79
store top_commit_time_local inside of BranchInfo
UUGTech Apr 14, 2024
df47f5d
Merge remote-tracking branch 'origin/feat-sort-branch' into feat-sort…
UUGTech Apr 14, 2024
3826d4b
Merge remote-tracking branch 'origin/master' into feat-sort-branch
UUGTech Apr 14, 2024
73d6171
fix clippy
UUGTech Apr 14, 2024
9e249e7
change the key to sort
UUGTech Apr 14, 2024
192adeb
Merge branch 'master' into feat-sort-branch
extrawurst Apr 14, 2024
7d174fe
Merge branch 'master'
UUGTech Apr 24, 2024
75fb648
fix branch_sort popup style
UUGTech Apr 24, 2024
38bfc84
keep selected index in sort
UUGTech Apr 24, 2024
cad4c63
cargo fmt
UUGTech Apr 24, 2024
630828e
bold style
UUGTech Apr 24, 2024
71f626e
update popup selection style
UUGTech May 1, 2024
d5e97de
Merge remote-tracking branch 'origin/master' into feat-sort-branch
UUGTech May 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added
* add sort_by popup to branchlist [[@UUGTech](https://github.com/UUGTech)]([#2146](https://github.com/extrawurst/gitui/issues/2146))

## [0.26.0+1] - 2024-04-14

**0.26.1**
Expand Down
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,6 +49,8 @@ serde = "1.0"
shellexpand = "3.1"
simplelog = { version = "0.12", default-features = false }
struct-patch = "0.4"
strum = "0.25"
strum_macros = "0.25"
syntect = { version = "5.2", default-features = false, features = [
"parsing",
"default-syntaxes",
Expand Down
1 change: 1 addition & 0 deletions asyncgit/Cargo.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,6 +13,7 @@ keywords = ["git"]

[dependencies]
bitflags = "2"
chrono = { version = "0.4", default-features = false, features = ["clock"] }
crossbeam-channel = "0.5"
dirs = "5.0"
easy-cast = "0.5"
Expand Down
15 changes: 15 additions & 0 deletions asyncgit/src/sync/branch/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -11,8 +11,10 @@ use crate::{
sync::{
remotes::get_default_remote_for_push_in_repo,
repository::repo, utils::get_head_repo, CommitId,
CommitSignature,
},
};
use chrono::{DateTime, Local, TimeZone};
use git2::{Branch, BranchType, Repository};
use scopetime::scope_time;
use std::collections::HashSet;
Expand DownExpand Up@@ -92,6 +94,12 @@ pub struct BranchInfo {
///
pub top_commit: CommitId,
///
pub top_commit_time: i64,
///
pub top_commit_time_local: Option<DateTime<Local>>,
Comment on lines +97 to +99

@UUGTechUUGTechApr 14, 2024

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added top_commit_time_local inside of BranchInfo.
But this could be None. I thought we should keep top_commit_time: i64 here. (top_commit_time is used for sorting) What do you think?

///
pub top_commit_author: String,
///
pub details: BranchDetails,
}

Expand DownExpand Up@@ -181,13 +189,20 @@ pub fn get_branches_info(
})
};

let author = CommitSignature::from(&top_commit.author());

Ok(BranchInfo {
name: bytes2string(name_bytes)?,
reference,
top_commit_message: bytes2string(
top_commit.summary_bytes().unwrap_or_default(),
)?,
top_commit: top_commit.id().into(),
top_commit_time: top_commit.time().seconds(),
top_commit_time_local: Local
.timestamp_opt(top_commit.time().seconds(), 0)
.earliest(),
top_commit_author: author.name,
details,
})
})
Expand Down
32 changes: 24 additions & 8 deletions src/app.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -10,14 +10,15 @@ use crate::{
options::{Options, SharedOptions},
popup_stack::PopupStack,
popups::{
AppOption, BlameFilePopup, BranchListPopup, CommitPopup,
CompareCommitsPopup, ConfirmPopup, CreateBranchPopup,
ExternalEditorPopup, FetchPopup, FileRevlogPopup,
FuzzyFindPopup, HelpPopup, InspectCommitPopup,
LogSearchPopupPopup, MsgPopup, OptionsPopup, PullPopup,
PushPopup, PushTagsPopup, RenameBranchPopup, ResetPopup,
RevisionFilesPopup, StashMsgPopup, SubmodulesListPopup,
TagCommitPopup, TagListPopup,
AppOption, BlameFilePopup, BranchListPopup, BranchSortPopup,
CommitPopup, CompareCommitsPopup, ConfirmPopup,
CreateBranchPopup, ExternalEditorPopup, FetchPopup,
FileRevlogPopup, FuzzyFindPopup, HelpPopup,
InspectCommitPopup, LogSearchPopupPopup, MsgPopup,
OptionsPopup, PullPopup, PushPopup, PushTagsPopup,
RenameBranchPopup, ResetPopup, RevisionFilesPopup,
StashMsgPopup, SubmodulesListPopup, TagCommitPopup,
TagListPopup,
},
queue::{
Action, AppTabs, InternalEvent, NeedsUpdate, Queue,
Expand DownExpand Up@@ -88,6 +89,7 @@ pub struct App {
create_branch_popup: CreateBranchPopup,
rename_branch_popup: RenameBranchPopup,
select_branch_popup: BranchListPopup,
sort_branch_popup: BranchSortPopup,
options_popup: OptionsPopup,
submodule_popup: SubmodulesListPopup,
tags_popup: TagListPopup,
Expand DownExpand Up@@ -196,6 +198,7 @@ impl App {
submodule_popup: SubmodulesListPopup::new(&env),
log_search_popup: LogSearchPopupPopup::new(&env),
fuzzy_find_popup: FuzzyFindPopup::new(&env),
sort_branch_popup: BranchSortPopup::new(&env),
do_quit: QuitState::None,
cmdbar: RefCell::new(CommandBar::new(
env.theme.clone(),
Expand DownExpand Up@@ -468,6 +471,7 @@ impl App {
[
log_search_popup,
fuzzy_find_popup,
sort_branch_popup,
msg_popup,
confirm_popup,
commit_popup,
Expand DownExpand Up@@ -517,6 +521,7 @@ impl App {
reset_popup,
create_branch_popup,
rename_branch_popup,
sort_branch_popup,
revision_files_popup,
fuzzy_find_popup,
log_search_popup,
Expand DownExpand Up@@ -803,6 +808,17 @@ impl App {
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}
InternalEvent::OpenBranchSortPopup(sort_by) => {
self.sort_branch_popup.open(sort_by)?;
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}
InternalEvent::BranchListSort(sort_by) => {
self.select_branch_popup.change_sort_by(sort_by);
self.select_branch_popup.sort()?;
flags
.insert(NeedsUpdate::ALL | NeedsUpdate::COMMANDS);
}
InternalEvent::OptionSwitched(o) => {
match o {
AppOption::StatusShowUntracked => {
Expand Down
12 changes: 12 additions & 0 deletions src/components/mod.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,6 +18,8 @@ pub use commitlist::CommitList;
pub use cred::CredComponent;
pub use diff::DiffComponent;
pub use revision_files::RevisionFilesComponent;
use strum::EnumIter;
use strum_macros::{EnumCount, EnumIs};
pub use syntax_text::SyntaxTextComponent;
pub use textinput::{InputType, TextInputComponent};
pub use utils::{
Expand DownExpand Up@@ -191,6 +193,16 @@ pub enum FuzzyFinderTarget {
Files,
}

#[derive(Copy, Clone, EnumCount, EnumIs, EnumIter)]
pub enum BranchListSortBy {
BranchNameAsc,
BranchNameDesc,
LastCommitTimeDesc,
LastCommitTimeAsc,
LastCommitAuthorAsc,
LastCommitAuthorDesc,
}

impl EventState {
pub fn is_consumed(&self) -> bool {
*self == Self::Consumed
Expand Down
2 changes: 2 additions & 0 deletions src/keys/key_list.rs
Original file line numberDiff line numberDiff line change
Expand Up@@ -108,6 +108,7 @@ pub struct KeysList {
pub open_file_tree: GituiKeyEvent,
pub file_find: GituiKeyEvent,
pub branch_find: GituiKeyEvent,
pub branch_sort: GituiKeyEvent,
pub force_push: GituiKeyEvent,
pub fetch: GituiKeyEvent,
pub pull: GituiKeyEvent,
Expand DownExpand Up@@ -205,6 +206,7 @@ impl Default for KeysList {
open_file_tree: GituiKeyEvent::new(KeyCode::Char('F'), KeyModifiers::SHIFT),
file_find: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::empty()),
branch_find: GituiKeyEvent::new(KeyCode::Char('f'), KeyModifiers::empty()),
branch_sort: GituiKeyEvent::new(KeyCode::Char('S'), KeyModifiers::SHIFT),
diff_hunk_next: GituiKeyEvent::new(KeyCode::Char('n'), KeyModifiers::empty()),
diff_hunk_prev: GituiKeyEvent::new(KeyCode::Char('p'), KeyModifiers::empty()),
stage_unstage_item: GituiKeyEvent::new(KeyCode::Enter, KeyModifiers::empty()),
Expand Down
Loading