mirror of
https://github.com/textmate/textmate.git
synced 2026-04-28 03:00:34 -04:00
Introduce API for proper bundle item titles
When a bundle item’s title contains “«unit» / Selection” then the UI should only show either “«unit»” or “Selection” depending on whether or not the text view has selected text.
This commit is contained in:
@@ -22,6 +22,7 @@ PUBLIC @interface BundleItemChooser : NSObject <FilterListDataSource>
|
||||
{
|
||||
OBJC_WATCH_LEAKS(BundleItemChooser);
|
||||
scope::context_t scope;
|
||||
BOOL hasSelection;
|
||||
std::vector<bundles::item_ptr> all_items;
|
||||
std::set<oak::uuid_t> items_filtered_by_scope;
|
||||
BOOL searchAllScopes;
|
||||
@@ -34,6 +35,7 @@ PUBLIC @interface BundleItemChooser : NSObject <FilterListDataSource>
|
||||
+ (id)bundleItemChooserForScope:(scope::context_t const&)aScope;
|
||||
@property (nonatomic, retain) NSString* filterString;
|
||||
@property (nonatomic, assign) BOOL keyEquivalentSearch;
|
||||
@property (nonatomic, assign) BOOL textViewHasSelection;
|
||||
@property (nonatomic, assign) BOOL searchAllScopes;
|
||||
@property (nonatomic, assign) search::type searchType;
|
||||
@end
|
||||
|
||||
@@ -299,9 +299,9 @@ static NSString* const AllScopes = @"AllScopes";
|
||||
@end
|
||||
|
||||
@implementation BundleItemChooser
|
||||
@synthesize keyEquivalentSearch, searchAllScopes, searchType;
|
||||
@synthesize keyEquivalentSearch, textViewHasSelection = hasSelection, searchAllScopes, searchType;
|
||||
|
||||
static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type searchType, scope::context_t const& scope)
|
||||
static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type searchType, scope::context_t const& scope, bool hasSelection)
|
||||
{
|
||||
int kindMask = 0;
|
||||
if(searchType == search::actions)
|
||||
@@ -313,7 +313,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
|
||||
|
||||
std::multimap<std::string, bundles::item_ptr, text::less_t> sorted;
|
||||
citerate(item, bundles::query(bundles::kFieldAny, NULL_STR, scope, kindMask, oak::uuid_t(), false))
|
||||
sorted.insert(std::make_pair((*item)->full_name(), *item));
|
||||
sorted.insert(std::make_pair(full_name_with_selection(*item, hasSelection), *item));
|
||||
|
||||
std::vector<bundles::item_ptr> res;
|
||||
std::transform(sorted.begin(), sorted.end(), back_inserter(res), [](std::pair<std::string, bundles::item_ptr> const& p){ return p.second; });
|
||||
@@ -357,9 +357,9 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
|
||||
if(newType != searchType || all_items.empty())
|
||||
{
|
||||
searchType = newType;
|
||||
all_items = relevant_items_in_scope(searchType, scope::wildcard);
|
||||
all_items = relevant_items_in_scope(searchType, scope::wildcard, hasSelection);
|
||||
|
||||
citerate(item, relevant_items_in_scope(searchType, scope))
|
||||
citerate(item, relevant_items_in_scope(searchType, scope, hasSelection))
|
||||
items_filtered_by_scope.insert((*item)->uuid());
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:FLDataSourceItemsDidChangeNotification object:self];
|
||||
}
|
||||
@@ -455,7 +455,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
|
||||
}
|
||||
else if(!filterString.empty())
|
||||
{
|
||||
double nameRank = oak::rank(filterString, all_items[index]->full_name());
|
||||
double nameRank = oak::rank(filterString, full_name_with_selection(all_items[index], hasSelection));
|
||||
double triggerRank = oak::rank(filterString, all_items[index]->value_for_field(bundles::kFieldTabTrigger));
|
||||
if(nameRank == 0 && triggerRank == 0)
|
||||
continue;
|
||||
@@ -479,10 +479,10 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
|
||||
- (NSAttributedString*)displayStringForItem:(BundleItemChooserItem*)item
|
||||
{
|
||||
NSUInteger index = [item index];
|
||||
std::string const& itemName = all_items[index]->full_name();
|
||||
std::string const itemName = full_name_with_selection(all_items[index], hasSelection);
|
||||
|
||||
std::vector< std::pair<size_t, size_t> > ranges;
|
||||
double nameRank = oak::rank(filterString, all_items[index]->full_name());
|
||||
double nameRank = oak::rank(filterString, full_name_with_selection(all_items[index], hasSelection));
|
||||
double triggerRank = oak::rank(filterString, all_items[index]->value_for_field(bundles::kFieldTabTrigger));
|
||||
if(nameRank > triggerRank)
|
||||
oak::rank(text::lowercase(filterString), itemName, &ranges);
|
||||
@@ -506,7 +506,7 @@ static std::vector<bundles::item_ptr> relevant_items_in_scope (search::type sear
|
||||
std::string const& tabTrigger = all_items[index]->value_for_field(bundles::kFieldTabTrigger);
|
||||
if(tabTrigger != NULL_STR)
|
||||
{
|
||||
double nameRank = oak::rank(filterString, all_items[index]->full_name());
|
||||
double nameRank = oak::rank(filterString, full_name_with_selection(all_items[index], hasSelection));
|
||||
double triggerRank = oak::rank(filterString, tabTrigger);
|
||||
if(triggerRank > nameRank)
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace bundles
|
||||
{
|
||||
PUBLIC item_ptr show_menu_for_items (std::vector<item_ptr> const& items, CGPoint const& pos);
|
||||
PUBLIC item_ptr show_menu_for_items (std::vector<item_ptr> const& items, CGPoint const& pos, bool hasSelection = false);
|
||||
|
||||
} /* bundles */
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#import "menu.h"
|
||||
#import "query.h"
|
||||
#import <OakFoundation/NSString Additions.h>
|
||||
#import <text/ctype.h>
|
||||
#import <cf/cf.h>
|
||||
@@ -59,7 +60,7 @@ namespace bundles
|
||||
return res;
|
||||
}
|
||||
|
||||
item_ptr show_menu_for_items (std::vector<item_ptr> const& items, CGPoint const& pos)
|
||||
item_ptr show_menu_for_items (std::vector<item_ptr> const& items, CGPoint const& pos, bool hasSelection)
|
||||
{
|
||||
if(items.empty())
|
||||
return item_ptr();
|
||||
@@ -116,7 +117,7 @@ namespace bundles
|
||||
|
||||
std::multimap<std::string, item_ptr, text::less_t> ordering;
|
||||
iterate(item, includedItems)
|
||||
ordering.insert(std::make_pair((*item)->name(), *item));
|
||||
ordering.insert(std::make_pair(name_with_selection(*item, hasSelection), *item));
|
||||
std::transform(ordering.begin(), ordering.end(), back_inserter(menuItems), [](std::pair<std::string, item_ptr> const& p){ return p.second; });
|
||||
|
||||
menus.insert(std::make_pair(bundle->name(), menuItems));
|
||||
@@ -143,7 +144,7 @@ namespace bundles
|
||||
[menu addItem:[NSMenuItem separatorItem]];
|
||||
pendingSeparator = false;
|
||||
|
||||
NSMenuItem* menuItem = [menu addItemWithTitle:[NSString stringWithCxxString:(*item)->name()] action:@selector(takeSelectedItemIndexFrom:) keyEquivalent:@""];
|
||||
NSMenuItem* menuItem = [menu addItemWithTitle:[NSString stringWithCxxString:name_with_selection(*item, hasSelection)] action:@selector(takeSelectedItemIndexFrom:) keyEquivalent:@""];
|
||||
[menuItem setTarget:menuTarget];
|
||||
[menuItem setTag:key];
|
||||
|
||||
|
||||
@@ -263,4 +263,32 @@ namespace bundles
|
||||
return res;
|
||||
}
|
||||
|
||||
static std::string format_bundle_item_title (std::string title, bool hasSelection)
|
||||
{
|
||||
static std::string const kSelectionSubString = " / Selection";
|
||||
|
||||
std::string::size_type pos = title.find(kSelectionSubString);
|
||||
if(pos == 0 || pos == std::string::npos)
|
||||
return title;
|
||||
|
||||
if(hasSelection)
|
||||
{
|
||||
std::string::size_type from = title.rfind(' ', pos - 1);
|
||||
if(from == std::string::npos)
|
||||
return title.erase(0, pos + 3);
|
||||
return title.erase(from + 1, pos + 3 - from - 1);
|
||||
}
|
||||
return title.erase(pos, kSelectionSubString.size());
|
||||
}
|
||||
|
||||
std::string name_with_selection (item_ptr const& item, bool hasSelection)
|
||||
{
|
||||
return format_bundle_item_title(item->name(), hasSelection);
|
||||
}
|
||||
|
||||
std::string full_name_with_selection (item_ptr const& item, bool hasSelection)
|
||||
{
|
||||
return format_bundle_item_title(item->full_name(), hasSelection);
|
||||
}
|
||||
|
||||
} /* bundles */
|
||||
@@ -10,6 +10,8 @@ namespace bundles
|
||||
|
||||
PUBLIC std::vector<item_ptr> query (std::string const& field, std::string const& value, scope::context_t const& scope = scope::wildcard, int kind = kItemTypeCommand|kItemTypeDragCommand|kItemTypeGrammar|kItemTypeMacro|kItemTypeSnippet|kItemTypeProxy|kItemTypeTheme, oak::uuid_t const& bundle = oak::uuid_t(), bool filter = true, bool includeDisabledItems = false);
|
||||
PUBLIC item_ptr lookup (oak::uuid_t const& uuid);
|
||||
PUBLIC std::string name_with_selection (item_ptr const& item, bool hasSelection);
|
||||
PUBLIC std::string full_name_with_selection (item_ptr const& item, bool hasSelection);
|
||||
|
||||
} /* bundles */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user