From a2afeba6545be9307f6505fd7a29375e89a9075e Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 18 Jun 2023 15:38:38 +0200 Subject: Merging upstream version 20230618. Signed-off-by: Daniel Baumann --- .../recentFilesSearchProvider.js | 324 --------------------- 1 file changed, 324 deletions(-) delete mode 100644 extensions/vertical-workspaces/recentFilesSearchProvider.js (limited to 'extensions/vertical-workspaces/recentFilesSearchProvider.js') diff --git a/extensions/vertical-workspaces/recentFilesSearchProvider.js b/extensions/vertical-workspaces/recentFilesSearchProvider.js deleted file mode 100644 index b94d696..0000000 --- a/extensions/vertical-workspaces/recentFilesSearchProvider.js +++ /dev/null @@ -1,324 +0,0 @@ -/** - * Vertical Workspaces - * recentFilesSearchProvider.js - * - * @author GdH - * @copyright 2022 - 2023 - * @license GPL-3.0 - */ - -'use strict'; - -const { GLib, GObject, Gio, Gtk, Meta, St, Shell } = imports.gi; - -const Main = imports.ui.main; -const ExtensionUtils = imports.misc.extensionUtils; -const Me = ExtensionUtils.getCurrentExtension(); -const Settings = Me.imports.settings; -const _ = Me.imports.settings._; - -const shellVersion = Settings.shellVersion; - -const ModifierType = imports.gi.Clutter.ModifierType; - -let recentFilesSearchProvider; -let _enableTimeoutId = 0; - -// prefix helps to eliminate results from other search providers -// so it needs to be something less common -// needs to be accessible from vw module -var prefix = 'fq//'; - -var opt; - -const Action = { - NONE: 0, - CLOSE: 1, - CLOSE_ALL: 2, - MOVE_TO_WS: 3, - MOVE_ALL_TO_WS: 4 -} - -function init() { -} - -function getOverviewSearchResult() { - return Main.overview._overview.controls._searchController._searchResults; -} - - -function update(reset = false) { - opt = Me.imports.settings.opt; - if (!reset && opt.RECENT_FILES_SEARCH_PROVIDER_ENABLED && !recentFilesSearchProvider) { - enable(); - } else if (reset || !opt.RECENT_FILES_SEARCH_PROVIDER_ENABLED) { - disable(); - opt = null; - } -} - -function enable() { - // delay because Fedora had problem to register a new provider soon after Shell restarts - _enableTimeoutId = GLib.timeout_add( - GLib.PRIORITY_DEFAULT, - 2000, - () => { - if (recentFilesSearchProvider == null) { - recentFilesSearchProvider = new RecentFilesSearchProvider(opt); - getOverviewSearchResult()._registerProvider(recentFilesSearchProvider); - } - _enableTimeoutId = 0; - return GLib.SOURCE_REMOVE; - } - ); -} - -function disable() { - if (recentFilesSearchProvider) { - getOverviewSearchResult()._unregisterProvider(recentFilesSearchProvider); - recentFilesSearchProvider = null; - } - if (_enableTimeoutId) { - GLib.source_remove(_enableTimeoutId); - _enableTimeoutId = 0; - } -} - -function fuzzyMatch(term, text) { - let pos = -1; - const matches = []; - // convert all accented chars to their basic form and to lower case - const _text = text;//.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); - const _term = term.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); - - // if term matches the substring exactly, gains the highest weight - if (_text.includes(_term)) { - return 0; - } - - for (let i = 0; i < _term.length; i++) { - let c = _term[i]; - let p; - if (pos > 0) - p = _term[i - 1]; - while (true) { - pos += 1; - if (pos >= _text.length) { - return -1; - } - if (_text[pos] == c) { - matches.push(pos); - break; - } else if (_text[pos] == p) { - matches.pop(); - matches.push(pos); - } - } - } - - // add all position to get a weight of the result - // results closer to the beginning of the text and term characters closer to each other will gain more weight. - return matches.reduce((r, p) => r + p) - matches.length * matches[0] + matches[0]; -} - -function strictMatch(term, text) { - // remove diacritics and accents from letters - let s = text.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(); - let p = term.toLowerCase(); - let ps = p.split(/ +/); - - // allows to use multiple exact patterns separated by a space in arbitrary order - for (let w of ps) { // escape regex control chars - if (!s.match(w.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))) { - return -1; - } - } - return 0; -} - -function makeResult(window, i) { - const app = Shell.WindowTracker.get_default().get_window_app(window); - const appName = app ? app.get_name() : 'Unknown'; - const windowTitle = window.get_title(); - const wsIndex = window.get_workspace().index(); - - return { - 'id': i, - // convert all accented chars to their basic form and lower case for search - 'name': `${wsIndex + 1}: ${windowTitle} ${appName}`.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase(), - 'appName': appName, - 'windowTitle': windowTitle, - 'window': window - } -} - -const closeSelectedRegex = /^\/x!$/; -const closeAllResultsRegex = /^\/xa!$/; -const moveToWsRegex = /^\/m[0-9]+$/; -const moveAllToWsRegex = /^\/ma[0-9]+$/; - -var RecentFilesSearchProvider = class RecentFilesSearchProvider { - constructor(gOptions) { - this._gOptions = gOptions; - this.appInfo = Gio.AppInfo.create_from_commandline('/usr/bin/nautilus -ws recent:///', 'Recent Files', null); - //this.appInfo = Shell.AppSystem.get_default().lookup_app('org.gnome.Nautilus.desktop').appInfo; - this.appInfo.get_description = () => _('Search recent files'); - this.appInfo.get_name = () => _('Recent Files'); - this.appInfo.get_id = () => 'org.gnome.Nautilus.desktop'; - this.appInfo.get_icon = () => Gio.icon_new_for_string('document-open-recent-symbolic'); - this.appInfo.should_show = () => true; - this.title = _('Recent Files Search Provider'), - this.canLaunchSearch = true; - this.isRemoteProvider = false; - } - - _getResultSet (terms) { - if (!terms[0].startsWith(prefix)) - return []; - // do not modify original terms - let termsCopy = [...terms]; - // search for terms without prefix - termsCopy[0] = termsCopy[0].replace(prefix, ''); - - const candidates = this.files; - const _terms = [].concat(termsCopy); - let match; - - const term = _terms.join(' '); - match = (s) => { - return fuzzyMatch(term, s); - } - - const results = []; - let m; - for (let id in candidates) { - const file = this.files[id]; - const name = `${file.get_age()}d: ${file.get_display_name()} ${file.get_uri_display().replace(`\/${file.get_display_name()}`, '')}`; - if (this._gOptions.get('searchFuzzy')) { - m = fuzzyMatch(term, name); - } else { - m = strictMatch(term, name); - } - if (m !== -1) { - results.push({ weight: m, id: id}); - } - } - - results.sort((a, b) => this.files[a.id].get_visited() < this.files[b.id].get_visited()); - - this.resultIds = results.map((item) => item.id); - return this.resultIds; - } - - getResultMetas (resultIds, callback = null) { - const metas = resultIds.map((id) => this.getResultMeta(id)); - if (shellVersion >= 43) { - return new Promise(resolve => resolve(metas)); - } else { - callback(metas); - } - } - - getResultMeta (resultId) { - const result = this.files[resultId]; - return { - 'id': resultId, - 'name': `${result.get_age()}: ${result.get_display_name()}`, - 'description': `${result.get_uri_display().replace(`\/${result.get_display_name()}`, '')}`, - 'createIcon': (size) => { - let icon = this.getIcon(result, size); - return icon; - }, - } - } - - getIcon(result, size) { - let file = Gio.File.new_for_uri(result.get_uri()); - let info = file.query_info(Gio.FILE_ATTRIBUTE_THUMBNAIL_PATH, - Gio.FileQueryInfoFlags.NONE, null); - let path = info.get_attribute_byte_string( - Gio.FILE_ATTRIBUTE_THUMBNAIL_PATH); - - let icon, gicon; - - if (path) { - gicon = Gio.FileIcon.new(Gio.File.new_for_path(path)); - } else { - const appInfo = Gio.AppInfo.get_default_for_type(result.get_mime_type(), false); - if (appInfo) - gicon = appInfo.get_icon(); - } - - if (gicon) { - icon = new St.Icon({ gicon, icon_size: size }); - } else { - icon = new St.Icon({ icon_name: 'icon-missing', icon_size: size }); - } - - return icon; - } - - launchSearch(terms, timeStamp) { - this._openNautilus('recent:///') - } - - _openNautilus(uri) { - try { - GLib.spawn_command_line_async(`nautilus -ws ${uri}`); - } catch (e) { - log(e); - } - } - - activateResult (resultId, terms, timeStamp) { - const file = this.files[resultId]; - - const [,,state] = global.get_pointer(); - //const isCtrlPressed = (state & ModifierType.CONTROL_MASK) != 0; - const isShiftPressed = (state & ModifierType.SHIFT_MASK) != 0; - - if (isShiftPressed) { - Main.overview.toggle(); - this._openNautilus(file.get_uri()); - } else { - const appInfo = Gio.AppInfo.get_default_for_type(file.get_mime_type(), false); - if (!(appInfo && appInfo.launch_uris([file.get_uri()], null))) { - this._openNautilus(file.get_uri()); - } - } - } - - getInitialResultSet (terms, callback, cancellable = null) { - if (shellVersion >=43) { - cancellable = callback; - } - - const filesDict = {}; - const files = Gtk.RecentManager.get_default().get_items().filter((f)=> f.exists()); - - for (let file of files) { - filesDict[file.get_uri()] = file; - } - - this.files = filesDict; - - if (shellVersion >= 43) { - return new Promise(resolve => resolve(this._getResultSet(terms))); - } else { - callback(this._getResultSet(terms)); - } - } - - filterResults (results, maxResults) { - return results.slice(0, maxResults); - } - - getSubsearchResultSet (previousResults, terms, callback, cancellable) { - // if we return previous results, quick typers get non-actual results - callback(this._getResultSet(terms)); - } - - createResultOjbect(resultMeta) { - return this.files[resultMeta.id]; - } -} -- cgit v1.2.3