diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9090e51f05..c97abbfbc5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -58,7 +58,7 @@ jobs: uses: flatpak/flatpak-github-actions/flatpak-builder@v6 with: bundle: code.flatpak - manifest-path: io.elementary.code.yml + manifest-path: com.github.jeremypw.dogfood-code-7.yml repository-name: appcenter repository-url: https://flatpak.elementary.io/repo.flatpakrepo cache-key: "flatpak-builder-${{ github.sha }}" diff --git a/README.md b/README.md index 9f440e8b3e..ffee34dcf3 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,4 @@ -# Code -[![Translation status](https://l10n.elementary.io/widgets/code/-/svg-badge.svg)](https://l10n.elementary.io/projects/code/?utm_source=widget) - +# Dogfood-code-7 ![Screenshot](data/screenshot.png?raw=true) ## Building, Testing, and Installation @@ -27,7 +25,7 @@ Run `meson build` to configure the build environment. Change to the build direct cd build ninja test -To install, use `ninja install`, then execute with `io.elementary.code` +To install, use `ninja install`, then execute with `com.github.jeremypw.dogfood-code-7` sudo ninja install - io.elementary.code + com.github.jeremypw.dogfood-code-7 diff --git a/data/code.policy.in.in b/data/code.policy.in.in index 9528044a13..5bbe5b0b4d 100644 --- a/data/code.policy.in.in +++ b/data/code.policy.in.in @@ -6,7 +6,7 @@ elementary https://github.com/elementary/code io.elementary.code - + Run Code as Administrator Authentication is required to run Code as Administrator diff --git a/data/io.elementary.code.desktop.in.in b/data/io.elementary.code.desktop.in.in index ae78f19e70..30bd85b3db 100644 --- a/data/io.elementary.code.desktop.in.in +++ b/data/io.elementary.code.desktop.in.in @@ -1,10 +1,10 @@ [Desktop Entry] Type=Application Name=@NAME@ -Comment=Edit code files -GenericName=Code Editor +Comment=Dogfood Code editor on eOS7 +GenericName=Experimental Code Editor Exec=@EXEC_NAME@ %U -Icon=io.elementary.code +Icon=missing-image Terminal=false Categories=Development;GTK;IDE;WebDevelopment; Keywords=text;IDE;scratch;code; diff --git a/data/io.elementary.code.gschema.xml b/data/io.elementary.code.gschema.xml index 400fe64e48..f96f75c0cb 100644 --- a/data/io.elementary.code.gschema.xml +++ b/data/io.elementary.code.gschema.xml @@ -1,24 +1,24 @@ - + - + - + - - + + "Normal" The saved state of the window. The saved state of the window. @@ -65,7 +65,7 @@ - + ['brackets-completion', 'detect-indent', 'editorconfig'] Enabled Plugins @@ -106,7 +106,7 @@ Highlight Matching Brackets Whether Code should highlight matching brackets. - + "For Selection" Draw spaces and tabs with symbols Draw spaces and tabs with symbols. "Never" is deprecated and not exposed in the UI. @@ -152,6 +152,11 @@ Remember the last focused document. Restore the focused document from a previous session when opening Code. + + '' + The active project path. + The path to the folder containing the active project. + '' The default build directory's relative path. @@ -182,7 +187,7 @@ Whether search term is a regex expression Whether the search should use the search term as a regex expression for matching. - + 'mixed' When text search is case sensitive Whether the text search is case sensitive never, always or only when search term is mixed case @@ -194,7 +199,7 @@ - + 'None' Default PasteBin text highlight @@ -212,7 +217,7 @@ - + [] Opened folders. diff --git a/data/io.elementary.code.plugins.spell.gschema.xml b/data/io.elementary.code.plugins.spell.gschema.xml index a4ff449abf..bfedb97dd9 100644 --- a/data/io.elementary.code.plugins.spell.gschema.xml +++ b/data/io.elementary.code.plugins.spell.gschema.xml @@ -1,6 +1,6 @@ - + 'en_US' Selected Spellcheck Language diff --git a/data/meson.build b/data/meson.build index b28891a23d..8c065cad21 100644 --- a/data/meson.build +++ b/data/meson.build @@ -4,12 +4,12 @@ foreach i : icon_sizes install_data( 'icons' / i + '.svg', install_dir: get_option('datadir') / 'icons' / 'hicolor' / i + 'x' + i / 'apps', - rename: meson.project_name() + '.svg' + rename: install_name + '.svg' ) install_data( 'icons' / i + '.svg', install_dir: get_option('datadir') / 'icons' / 'hicolor' / i + 'x' + i + '@2' / 'apps', - rename: meson.project_name() + '.svg' + rename: install_name + '.svg' ) endforeach @@ -20,7 +20,7 @@ install_data([ install_data([ 'fonts/BuilderBlocks.ttf', -], install_dir: get_option('datadir') / meson.project_name() / 'fonts') +], install_dir: get_option('datadir') / install_name / 'fonts') install_data( 'io.elementary.code.gschema.xml', @@ -29,12 +29,12 @@ install_data( ) config_data = configuration_data() -config_data.set('EXEC_NAME', meson.project_name()) +config_data.set('EXEC_NAME', install_name) if (branch != '') - config_data.set('NAME', 'Code - ' + branch) + config_data.set('NAME', 'Dogfood Code 7 - ' + branch) else - config_data.set('NAME', 'Code') + config_data.set('NAME', 'Dogfood Code 7') endif # Set the executable name and translate the desktop files @@ -46,7 +46,7 @@ desktop_in_file = configure_file( desktop_file = i18n.merge_file( input: desktop_in_file, - output: 'io.elementary.code.desktop', + output: install_name + '.desktop', po_dir: meson.project_source_root () / 'po' / 'extra', type: 'desktop', install_dir: get_option('datadir') / 'applications', @@ -55,7 +55,7 @@ desktop_file = i18n.merge_file( i18n.merge_file( input: 'code.metainfo.xml.in', - output: meson.project_name() + '.metainfo.xml', + output: install_name + '.metainfo.xml', po_dir: meson.project_source_root() / 'po' / 'extra', type: 'xml', install: true, @@ -65,19 +65,19 @@ i18n.merge_file( config_data = configuration_data() config_data.set('install_prefix', get_option('prefix')) config_data.set('bin_dir', get_option('bindir')) -config_data.set('exec_name', meson.project_name()) +config_data.set('exec_name', install_name) if get_option ('have_pkexec') policy_in = configure_file( input: 'code.policy.in.in', - output: meson.project_name() + '.policy.in', + output: install_name + '.policy.in', configuration: config_data, install: false, ) i18n.merge_file( input: policy_in, - output: meson.project_name() + '.policy', + output: install_name + '.policy', po_dir: meson.project_source_root () / 'po' / 'extra', install: true, install_dir: get_option('datadir') / 'polkit-1' / 'actions', diff --git a/io.elementary.code.yml b/io.elementary.code.yml index c0764fbf43..4fde73c719 100644 --- a/io.elementary.code.yml +++ b/io.elementary.code.yml @@ -1,8 +1,8 @@ -app-id: io.elementary.code +app-id: com.github.jeremypw.dogfood-code-7 runtime: io.elementary.Sdk # The outline plugin requires libvala which is only in the SDK, not the runtime runtime-version: '7.1' sdk: io.elementary.Sdk -command: io.elementary.code +command: com.github.jeremypw.dogfood-code-7 finish-args: - '--filesystem=xdg-run/gvfsd' - '--filesystem=host' diff --git a/meson.build b/meson.build index b600a80667..61eb8a3ea3 100644 --- a/meson.build +++ b/meson.build @@ -1,3 +1,4 @@ +# Original project from which fork was made project( 'io.elementary.code', 'vala', 'c', @@ -5,8 +6,11 @@ project( version: '7.4.0' ) +# Install under different name so may be run alongside original +install_name = 'com.github.jeremypw.dogfood-code-7' + add_project_arguments([ - '-DGETTEXT_PACKAGE="@0@"'.format(meson.project_name()) + '-DGETTEXT_PACKAGE="@0@"'.format(install_name) ], language: 'c', ) @@ -20,8 +24,8 @@ if get_option('have_pkexec') add_project_arguments('--define=HAVE_PKEXEC', language: 'vala') endif -libexecdir = get_option('prefix') / get_option('libexecdir') / meson.project_name() -pluginsdir = get_option('prefix') / get_option('libdir') / meson.project_name() / 'plugins' +libexecdir = get_option('prefix') / get_option('libexecdir') / install_name +pluginsdir = get_option('prefix') / get_option('libdir') / install_name / 'plugins' gnome = import('gnome') i18n = import('i18n') diff --git a/meson_options.txt b/meson_options.txt index a299238b52..4cf967c69d 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -1,3 +1,3 @@ option ('plugins', type : 'boolean', value : true) option('have_pkexec', type : 'boolean', value : 'true', description : 'Allow launching with pkexec. Should not be used in FlatPak') -option('development', type : 'boolean', value : false, description : 'Build is a development branch') +option('development', type : 'boolean', value : 'true', description : 'Build is a development branch') diff --git a/plugins/brackets-completion/meson.build b/plugins/brackets-completion/meson.build index 880e976202..68562b060f 100644 --- a/plugins/brackets-completion/meson.build +++ b/plugins/brackets-completion/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, ] shared_module( diff --git a/plugins/detect-indent/meson.build b/plugins/detect-indent/meson.build index d70c52eaa3..62e39fca44 100644 --- a/plugins/detect-indent/meson.build +++ b/plugins/detect-indent/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, ] shared_module( diff --git a/plugins/editorconfig/meson.build b/plugins/editorconfig/meson.build index eabe838183..1c6cdfe2a6 100644 --- a/plugins/editorconfig/meson.build +++ b/plugins/editorconfig/meson.build @@ -6,7 +6,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, meson.get_compiler('c').find_library('editorconfig') ] diff --git a/plugins/fuzzy-search/fuzzy-search-indexer.vala b/plugins/fuzzy-search/fuzzy-search-indexer.vala index 4c02bd3443..48fd187767 100644 --- a/plugins/fuzzy-search/fuzzy-search-indexer.vala +++ b/plugins/fuzzy-search/fuzzy-search-indexer.vala @@ -75,7 +75,7 @@ public class Scratch.Services.FuzzySearchIndexer : GLib.Object { processing_queue = new Gee.ConcurrentList (); project_paths = new Gee.HashMap (); - folder_settings = new GLib.Settings ("io.elementary.code.folder-manager"); + folder_settings = new GLib.Settings ("com.github.jeremypw.dogfood-code-7.folder-manager"); folder_settings.changed["opened-folders"].connect (handle_opened_projects_change); } diff --git a/plugins/fuzzy-search/fuzzy-search.vala b/plugins/fuzzy-search/fuzzy-search.vala index 2cff1cf2b7..7f9b90923f 100644 --- a/plugins/fuzzy-search/fuzzy-search.vala +++ b/plugins/fuzzy-search/fuzzy-search.vala @@ -54,7 +54,7 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Peas.Activatable { window = w; - folder_settings = new GLib.Settings ("io.elementary.code.folder-manager"); + folder_settings = new GLib.Settings ("com.github.jeremypw.dogfood-code-7.folder-manager"); add_actions (); folder_settings.changed["opened-folders"].connect (handle_opened_projects_change); }); @@ -118,7 +118,7 @@ public class Scratch.Plugins.FuzzySearch: Peas.ExtensionBase, Peas.Activatable { } private void fuzzy_find () { - var settings = new GLib.Settings ("io.elementary.code.folder-manager"); + var settings = new GLib.Settings ("com.github.jeremypw.dogfood-code-7.folder-manager"); string[] opened_folders = settings.get_strv ("opened-folders"); if (opened_folders == null || opened_folders.length < 1) { diff --git a/plugins/fuzzy-search/meson.build b/plugins/fuzzy-search/meson.build index 5a717fcd1f..aee6ea03e9 100644 --- a/plugins/fuzzy-search/meson.build +++ b/plugins/fuzzy-search/meson.build @@ -11,7 +11,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, ] shared_module( diff --git a/plugins/highlight-word-selection/highlight-word-selection.vala b/plugins/highlight-word-selection/highlight-word-selection.vala index 5896b5d43e..4c989c36c4 100644 --- a/plugins/highlight-word-selection/highlight-word-selection.vala +++ b/plugins/highlight-word-selection/highlight-word-selection.vala @@ -23,9 +23,7 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A Scratch.MainWindow? main_window = null; Gtk.SourceSearchContext? current_search_context = null; - // Consts - // Pneumonoultramicroscopicsilicovolcanoconiosis longest word in a major dictionary @ 45 - private const uint SELECTION_HIGHLIGHT_MAX_CHARS = 45; + private const uint SELECTION_HIGHLIGHT_MAX_CHARS = 255; Scratch.Services.Interface plugins; public Object object { owned get; construct; } @@ -36,12 +34,10 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A plugins = (Scratch.Services.Interface) object; plugins.hook_document.connect ((doc) => { if (current_source != null) { - current_source.deselected.disconnect (on_deselection); current_source.selection_changed.disconnect (on_selection_changed); } current_source = doc.source_view; - current_source.deselected.connect (on_deselection); current_source.selection_changed.connect (on_selection_changed); }); @@ -50,13 +46,13 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A }); } - public void on_selection_changed (ref Gtk.TextIter start, ref Gtk.TextIter end) { + public void on_selection_changed (string selected_text, ref Gtk.TextIter start, ref Gtk.TextIter end) { var window_search_context = main_window != null ? main_window.search_bar.search_context : null; - - if (window_search_context == null || + if (selected_text != "" && + (window_search_context == null || window_search_context.settings.search_text == "" || - window_search_context.get_occurrences_count () == 0) { - // Perform plugin selection when there is no ongoing and successful search + window_search_context.get_occurrences_count () == 0)) { + // Perform plugin selection when there is no ongoing and successful search current_search_context = new Gtk.SourceSearchContext ( (Gtk.SourceBuffer)current_source.buffer, null @@ -118,13 +114,13 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A ); // Ensure no leading or trailing space - var selected_text = start.get_text (end).strip (); + var stripped_selected_words = start.get_text (end).strip (); - if (selected_text.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) { + if (stripped_selected_words.char_count () > SELECTION_HIGHLIGHT_MAX_CHARS) { return; } - current_search_context.settings.search_text = selected_text; + current_search_context.settings.search_text = stripped_selected_words; current_search_context.set_highlight (true); } else if (current_search_context != null) { // Cancel existing search @@ -133,16 +129,8 @@ public class Scratch.Plugins.HighlightSelectedWords : Peas.ExtensionBase, Peas.A } } - public void on_deselection () { - if (current_search_context != null) { - current_search_context.set_highlight (false); - current_search_context = null; - } - } - public void deactivate () { if (current_source != null) { - current_source.deselected.disconnect (on_deselection); current_source.selection_changed.disconnect (on_selection_changed); } } diff --git a/plugins/highlight-word-selection/meson.build b/plugins/highlight-word-selection/meson.build index 393f197b2f..6e66ed18c6 100644 --- a/plugins/highlight-word-selection/meson.build +++ b/plugins/highlight-word-selection/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, ] shared_module( diff --git a/plugins/markdown-actions/meson.build b/plugins/markdown-actions/meson.build index 529dd12128..0a648e7757 100644 --- a/plugins/markdown-actions/meson.build +++ b/plugins/markdown-actions/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep, + dogfood_code_core_dep, ] shared_module( diff --git a/plugins/pastebin/meson.build b/plugins/pastebin/meson.build index f18e644d41..2ea812da69 100644 --- a/plugins/pastebin/meson.build +++ b/plugins/pastebin/meson.build @@ -8,7 +8,7 @@ module_files = [ soup_dep = dependency('libsoup-2.4') module_deps = [ - codecore_dep, + dogfood_code_core_dep, soup_dep ] diff --git a/plugins/preserve-indent/meson.build b/plugins/preserve-indent/meson.build index bd9c5596bd..4bdc779716 100644 --- a/plugins/preserve-indent/meson.build +++ b/plugins/preserve-indent/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep + dogfood_code_core_dep ] shared_module( diff --git a/plugins/spell/meson.build b/plugins/spell/meson.build index 6d64af66be..f6f58e85d0 100644 --- a/plugins/spell/meson.build +++ b/plugins/spell/meson.build @@ -7,7 +7,7 @@ module_files = [ spell_dep = dependency('gtkspell3-3.0') module_deps = [ - codecore_dep, + dogfood_code_core_dep, spell_dep ] diff --git a/plugins/vim-emulation/meson.build b/plugins/vim-emulation/meson.build index 6017f329d5..82a3908cd1 100644 --- a/plugins/vim-emulation/meson.build +++ b/plugins/vim-emulation/meson.build @@ -5,7 +5,7 @@ module_files = [ ] module_deps = [ - codecore_dep + dogfood_code_core_dep ] shared_module( diff --git a/plugins/word-completion/meson.build b/plugins/word-completion/meson.build index 247b0e60ad..7cafda64ad 100644 --- a/plugins/word-completion/meson.build +++ b/plugins/word-completion/meson.build @@ -8,7 +8,7 @@ module_files = [ ] module_deps = [ - codecore_dep + dogfood_code_core_dep ] shared_module( diff --git a/src/Application.vala b/src/Application.vala index 10c131d380..ff2f2f2e7a 100644 --- a/src/Application.vala +++ b/src/Application.vala @@ -91,7 +91,7 @@ namespace Scratch { /* Only allow running with root privileges using pkexec, not using sudo */ if (Posix.getuid () == 0 && GLib.Environment.get_variable ("PKEXEC_UID") == null) { #if HAVE_PKEXEC - warning ("Running Code using sudo is not possible. Use: pkexec io.elementary.code"); + warning ("Running Code using sudo is not possible. Use: pkexec com.github.jeremypw.dogfood-code-7"); #endif quit (); return 1; diff --git a/src/FolderManager/FileView.vala b/src/FolderManager/FileView.vala index c9efd85bbf..228982f641 100644 --- a/src/FolderManager/FileView.vala +++ b/src/FolderManager/FileView.vala @@ -35,6 +35,7 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane public const string ACTION_CHANGE_BRANCH = "change-branch"; public const string ACTION_CLOSE_FOLDER = "close-folder"; public const string ACTION_CLOSE_OTHER_FOLDERS = "close-other-folders"; + public const string ACTION_SET_ACTIVE_PROJECT = "set-active-project"; private const ActionEntry[] ACTION_ENTRIES = { { ACTION_LAUNCH_APP_WITH_FILE_PATH, action_launch_app_with_file_path, "as" }, @@ -46,7 +47,8 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane { ACTION_NEW_FILE, add_new_file, "s" }, { ACTION_NEW_FOLDER, add_new_folder, "s"}, { ACTION_CLOSE_FOLDER, action_close_folder, "s"}, - { ACTION_CLOSE_OTHER_FOLDERS, action_close_other_folders, "s"} + { ACTION_CLOSE_OTHER_FOLDERS, action_close_other_folders, "s"}, + { ACTION_SET_ACTIVE_PROJECT, action_set_active_project, "s"} }; private GLib.Settings settings; @@ -60,11 +62,6 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane public ActionGroup toplevel_action_group { get; private set; } public string icon_name { get; set; } public string title { get; set; } - public string active_project_path { - get { - return git_manager.active_project_path; - } - } public FileView (Scratch.Services.PluginsManager plugins_manager) { plugins = plugins_manager; @@ -75,7 +72,7 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane icon_name = "folder-symbolic"; title = _("Folders"); - settings = new GLib.Settings ("io.elementary.code.folder-manager"); + settings = new GLib.Settings ("com.github.jeremypw.dogfood-code-7.folder-manager"); git_manager = Scratch.Services.GitManager.get_instance (); @@ -119,10 +116,30 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane if (project_folder_item != folder_root) { toplevel_action_group.activate_action (MainWindow.ACTION_CLOSE_PROJECT_DOCS, new Variant.string (project_folder_item.path)); root.remove (project_folder_item); - Scratch.Services.GitManager.get_instance ().remove_project (project_folder_item); + git_manager.remove_project (project_folder_item); } } + //Make remaining project the active one + git_manager.active_project_path = path; + + write_settings (); + } + + private void action_set_active_project (SimpleAction action, GLib.Variant? parameter) { + warning ("set active project"); + var path = parameter.get_string (); + if (path == null || path == "") { + return; + } + + var folder_root = find_path (root, path) as ProjectFolderItem; + if (folder_root == null) { + return; + } + + git_manager.active_project_path = path; + write_settings (); } @@ -176,14 +193,9 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane selected = null; } - public void collapse_other_projects (string? keep_open_path = null) { + public void collapse_other_projects () { unowned string path; - if (keep_open_path == null) { - path = git_manager.active_project_path; - } else { - path = keep_open_path; - git_manager.active_project_path = path; - } + path = git_manager.active_project_path; foreach (var child in root.children) { var project_folder = ((ProjectFolderItem) child); @@ -528,10 +540,13 @@ public class Scratch.FolderManager.FileView : Code.Widgets.SourceList, Code.Pane rename_items_with_same_name (child_folder); } } - Scratch.Services.GitManager.get_instance ().remove_project (folder_root); + + git_manager.remove_project (folder_root); write_settings (); }); + // Do not assume this is the active folder + write_settings (); } diff --git a/src/FolderManager/ProjectFolderItem.vala b/src/FolderManager/ProjectFolderItem.vala index 9998db6be3..1e0c8434a9 100644 --- a/src/FolderManager/ProjectFolderItem.vala +++ b/src/FolderManager/ProjectFolderItem.vala @@ -134,16 +134,28 @@ namespace Scratch.FolderManager { warning (e.message); } - var open_in_terminal_pane_item = new GLib.MenuItem ( - _("Open in Terminal Pane"), - GLib.Action.print_detailed_name ( - MainWindow.ACTION_PREFIX + MainWindow.ACTION_OPEN_IN_TERMINAL, - new Variant.string ( - Services.GitManager.get_instance ().get_default_build_dir (path) + MenuItem set_active_folder_item; + if (is_git_repo) { + set_active_folder_item = new GLib.MenuItem ( + _("Set as Active Project"), + GLib.Action.print_detailed_name ( + FileView.ACTION_PREFIX + FileView.ACTION_SET_ACTIVE_PROJECT, + new Variant.string (file.path) ) - ) - ); - open_in_terminal_pane_item.set_attribute_value ( + ); + } else { + set_active_folder_item = new GLib.MenuItem ( + _("Open in Terminal Pane"), + GLib.Action.print_detailed_name ( + MainWindow.ACTION_PREFIX + MainWindow.ACTION_OPEN_IN_TERMINAL, + new Variant.string ( + Services.GitManager.get_instance ().get_default_build_dir (path) + ) + ) + ); + } + + set_active_folder_item.set_attribute_value ( "accel", Utils.get_accel_for_action ( GLib.Action.print_detailed_name ( @@ -154,7 +166,7 @@ namespace Scratch.FolderManager { ); var external_actions_section = new GLib.Menu (); - external_actions_section.append_item (open_in_terminal_pane_item); + external_actions_section.append_item (set_active_folder_item); external_actions_section.append_item (create_submenu_for_open_in (file_type)); var folder_actions_section = new GLib.Menu (); diff --git a/src/MainWindow.vala b/src/MainWindow.vala index 34fe7d93db..c7081469b4 100644 --- a/src/MainWindow.vala +++ b/src/MainWindow.vala @@ -27,6 +27,17 @@ namespace Scratch { public Scratch.Application app { get; private set; } public bool restore_docs { get; construct; } public RestoreOverride restore_override { get; construct set; } + public string default_globalsearch_path { + owned get { + if (document_view.current_document != null) { + if (document_view.current_document.project_path != "") { + return document_view.current_document.project_path; + } + } + + return git_manager.active_project_path; + } + } public Scratch.Widgets.DocumentView document_view; @@ -235,9 +246,9 @@ namespace Scratch { ); if (Constants.BRANCH != "") { - base_title = _("Code (%s)").printf (Constants.BRANCH); + base_title = _("Dogfood Code 7 (%s)").printf (Constants.BRANCH); } else { - base_title = _("Code"); + base_title = _("Dogfood Code 7"); } Hdy.init (); @@ -618,7 +629,6 @@ namespace Scratch { title = _("%s - %s").printf (doc.get_basename (), base_title); toolbar.set_document_focus (doc); - git_manager.active_project_path = doc.source_view.project.path; folder_manager_view.select_path (doc.file.get_path ()); // Must follow setting focus document for editorconfig plug @@ -1200,8 +1210,10 @@ namespace Scratch { } private void action_find_global (SimpleAction action, Variant? param) { + var selected_text = ""; + var search_path = ""; + var current_doc = get_current_document (); - string selected_text = ""; if (current_doc != null) { selected_text = current_doc.get_selected_text (false); } @@ -1221,7 +1233,19 @@ namespace Scratch { term = search_bar.search_entry.text; } - folder_manager_view.search_global (get_target_path_for_actions (param), term); + if (param != null && param.get_string () != "") { + search_path = param.get_string (); + } else { + search_path = default_globalsearch_path; + } + + if (search_path != "") { + folder_manager_view.search_global (search_path, term); + } else { + // Fallback to standard search + warning ("Unable to perform global search - search document instead"); + action_fetch (action, param); + } } private void update_find_actions () { @@ -1232,9 +1256,9 @@ namespace Scratch { Utils.action_from_group (ACTION_SHOW_FIND, actions).set_enabled (is_current_doc); Utils.action_from_group (ACTION_FIND_NEXT, actions).set_enabled (is_current_doc); Utils.action_from_group (ACTION_FIND_PREVIOUS, actions).set_enabled (is_current_doc); + var can_global_search = is_current_doc || git_manager.active_project_path != null; + Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (can_global_search); - var is_active_project = git_manager.active_project_path != ""; - Utils.action_from_group (ACTION_FIND_GLOBAL, actions).set_enabled (is_active_project); return Source.REMOVE; }); } diff --git a/src/Services/Document.vala b/src/Services/Document.vala index 20fae404a5..528570095a 100644 --- a/src/Services/Document.vala +++ b/src/Services/Document.vala @@ -65,6 +65,16 @@ namespace Scratch.Services { } } + public string project_path { + owned get { + if (source_view.project != null) { + return source_view.project.path; + } else { + return ""; + } + } + } + private string _title = ""; public string title { get { return _title; } diff --git a/src/Services/GitManager.vala b/src/Services/GitManager.vala index 6001473cf4..3b43bb88aa 100644 --- a/src/Services/GitManager.vala +++ b/src/Services/GitManager.vala @@ -44,9 +44,10 @@ namespace Scratch.Services { return instance; } - private GitManager () { + construct { // Used to populate the ChooseProject popover in sorted order project_liststore = new ListStore (typeof (FolderManager.ProjectFolderItem)); + settings.bind ("active-project-path", this, "active-project-path", DEFAULT); } public MonitoredRepository? add_project (FolderManager.ProjectFolderItem root_folder) { @@ -72,8 +73,7 @@ namespace Scratch.Services { ); } - //Ensure active_project_path always set - active_project_path = root_path; + // No longer need to set default project (restored from settings or left unset) return project_gitrepo_map.@get (root_path); } diff --git a/src/Widgets/ChooseProjectButton.vala b/src/Widgets/ChooseProjectButton.vala index 79f597435f..a16ec37ee6 100644 --- a/src/Widgets/ChooseProjectButton.vala +++ b/src/Widgets/ChooseProjectButton.vala @@ -18,18 +18,9 @@ public class Code.ChooseProjectButton : Gtk.MenuButton { private const string NO_PROJECT_SELECTED = N_("No Project Selected"); + private const string PROJECT_TOOLTIP = N_("Active Git Project: %s"); private Gtk.Label label_widget; private Gtk.ListBox project_listbox; - public unowned Gtk.RadioButton? group_source { - get { - var first_row = project_listbox.get_row_at_index (0); - if (first_row != null) { - return ((ProjectRow)first_row).project_radio; - } else { - return null; - } - } - } public signal void project_chosen (); @@ -44,8 +35,6 @@ public class Code.ChooseProjectButton : Gtk.MenuButton { xalign = 0.0f }; - tooltip_text = _("Active Git project: %s").printf (_(NO_PROJECT_SELECTED)); - var grid = new Gtk.Grid () { halign = Gtk.Align.START }; @@ -97,6 +86,7 @@ public class Code.ChooseProjectButton : Gtk.MenuButton { popover = project_popover; var git_manager = Scratch.Services.GitManager.get_instance (); + git_manager.project_liststore.items_changed.connect ((src, pos, n_removed, n_added) => { var rows = project_listbox.get_children (); for (int index = (int)pos; index < pos + n_removed; index++) { @@ -111,89 +101,81 @@ public class Code.ChooseProjectButton : Gtk.MenuButton { project_listbox.insert (row, index); } } - - set_active_path (git_manager.active_project_path); - }); - - git_manager.notify["active-project-path"].connect (() => { - set_active_path (git_manager.active_project_path); }); project_listbox.remove.connect ((row) => { var project_row = row as ProjectRow; var current_project = Scratch.Services.GitManager.get_instance ().active_project_path; if (project_row.project_path == current_project) { - label_widget.label = _(NO_PROJECT_SELECTED); - label_widget.tooltip_text = _("Active Git project: %s").printf (_(NO_PROJECT_SELECTED)); Scratch.Services.GitManager.get_instance ().active_project_path = ""; + // Label and active_path will be updated automatically } }); project_listbox.row_activated.connect ((row) => { var project_entry = ((ProjectRow) row); - label_widget.label = project_entry.project_name; - var tooltip_text = Scratch.Utils.replace_home_with_tilde (project_entry.project_path); - label_widget.tooltip_text = _("Active Git project: %s").printf (tooltip_text); - Scratch.Services.GitManager.get_instance ().active_project_path = project_entry.project_path; - project_entry.active = true; + git_manager.active_project_path = project_entry.project_path; project_chosen (); }); + + realize.connect (() => { + set_active_path (git_manager.active_project_path); + git_manager.notify["active-project-path"].connect (() => { + // Sync menubutton states + set_active_path (git_manager.active_project_path); + // Signal window to update as required (e.g. terminal) + project_chosen (); + }); + }); } + // Set appearance (only) of project chooser button and list according to active path private void set_active_path (string active_path) { foreach (var child in project_listbox.get_children ()) { - var project_entry = ((ProjectRow) child); - if (active_path.has_prefix (project_entry.project_path + Path.DIR_SEPARATOR_S)) { - project_listbox.row_activated (project_entry); - break; - } + var project_row = ((ProjectRow) child); + // All paths must not end in directory separator so can be compared directly + project_row.active = active_path == project_row.project_path; + } + + if (active_path != "") { + label_widget.label = Path.get_basename (active_path); + tooltip_text = _(PROJECT_TOOLTIP).printf (Scratch.Utils.replace_home_with_tilde (active_path)); + } else { + label_widget.label = Path.get_basename (_(NO_PROJECT_SELECTED)); + tooltip_text = _(PROJECT_TOOLTIP).printf (_(NO_PROJECT_SELECTED)); } } private Gtk.Widget create_project_row (Scratch.FolderManager.ProjectFolderItem project_folder) { - var project_row = new ProjectRow (project_folder.file.file.get_path (), group_source); - // Handle renaming of project; - project_folder.bind_property ("name", project_row.project_radio, "label", BindingFlags.DEFAULT | BindingFlags.SYNC_CREATE, - (binding, srcval, ref targetval) => { - var label = srcval.get_string (); - targetval.set_string (label); - if (project_row.active) { - label_widget.label = label; - } - - return true; - } - ); + var project_path = project_folder.file.file.get_path (); + var project_row = new ProjectRow (project_path); + // Project folder items cannot be renamed in UI, no need to handle return project_row; } public class ProjectRow : Gtk.ListBoxRow { + private Gtk.CheckButton check_button; public bool active { get { - return project_radio.active; + return check_button.active; } set { - if (value) { - project_radio.active = true; - } + check_button.active = value; } } public string project_path { get; construct; } public string project_name { get { - return project_radio.label; + return check_button.label; } } - public Gtk.RadioButton project_radio { get; construct; } - - public ProjectRow (string project_path, Gtk.RadioButton? group_source ) { + public ProjectRow (string project_path) { Object ( - project_path: project_path, - project_radio: new Gtk.RadioButton.with_label_from_widget (group_source, Path.get_basename (project_path)) + project_path: project_path ); } @@ -202,8 +184,9 @@ public class Code.ChooseProjectButton : Gtk.MenuButton { } construct { - add (project_radio); - project_radio.button_release_event.connect (() => { + check_button = new Gtk.CheckButton.with_label (Path.get_basename (project_path)); + add (check_button); + check_button.button_release_event.connect (() => { activate (); return Gdk.EVENT_PROPAGATE; }); diff --git a/src/Widgets/SourceView.vala b/src/Widgets/SourceView.vala index 2759b98bfe..88a772792c 100644 --- a/src/Widgets/SourceView.vala +++ b/src/Widgets/SourceView.vala @@ -31,21 +31,20 @@ namespace Scratch.Widgets { public FolderManager.ProjectFolderItem project { get; set; default = null; } private string font; - private uint selection_changed_timer = 0; private uint size_allocate_timer = 0; private Gtk.TextIter last_select_start_iter; private Gtk.TextIter last_select_end_iter; - private string selected_text = ""; + private string prev_selected_text = ""; private SourceGutterRenderer git_diff_gutter_renderer; - private const uint THROTTLE_MS = 400; + private const uint SIZE_ALLOCATION_THROTTLE_MS = 400; + private const uint SELECTION_CHANGE_THROTTLE_MS = 100; private double total_delta = 0; private const double SCROLL_THRESHOLD = 1.0; public signal void style_changed (Gtk.SourceStyleScheme style); // "selection_changed" signal now only emitted when the selected text changes (position ignored). Listened to by searchbar and highlight word selection plugin - public signal void selection_changed (Gtk.TextIter start_iter, Gtk.TextIter end_iter); - public signal void deselected (); + public signal void selection_changed (string selected_text, Gtk.TextIter start_iter, Gtk.TextIter end_iter); //lang can be null, in the case of *No highlight style* aka Normal text public Gtk.SourceLanguage? language { @@ -99,7 +98,9 @@ namespace Scratch.Widgets { var source_buffer = new Gtk.SourceBuffer (null); set_buffer (source_buffer); source_buffer.highlight_syntax = true; - source_buffer.mark_set.connect (on_mark_set); + source_buffer.mark_set.connect (schedule_selection_changed_event); + // Need to handle this signal else not all deselections are detected + source_buffer.mark_deleted.connect (schedule_selection_changed_event); highlight_current_line = true; var draw_spaces_tag = new Gtk.SourceTag ("draw_spaces"); @@ -189,7 +190,7 @@ namespace Scratch.Widgets { size_allocate.connect ((allocation) => { // Throttle for performance if (size_allocate_timer == 0) { - size_allocate_timer = Timeout.add (THROTTLE_MS, () => { + size_allocate_timer = Timeout.add (SIZE_ALLOCATION_THROTTLE_MS, () => { size_allocate_timer = 0; bottom_margin = calculate_bottom_margin (allocation.height); return GLib.Source.REMOVE; @@ -539,14 +540,12 @@ namespace Scratch.Widgets { /* Draw spaces in selection the same way if drawn at all */ if (selection && draw_spaces_state in (ScratchDrawSpacesState.FOR_SELECTION | ScratchDrawSpacesState.CURRENT | ScratchDrawSpacesState.ALWAYS)) { - buffer.apply_tag_by_name ("draw_spaces", start, end); return; } if (draw_spaces_state == ScratchDrawSpacesState.CURRENT && get_current_line (out start, out end)) { - buffer.apply_tag_by_name ("draw_spaces", start, end); } } @@ -597,49 +596,37 @@ namespace Scratch.Widgets { return (int) (height_in_px - (LINES_TO_KEEP * px_per_line)); } - void on_mark_set (Gtk.TextIter loc, Gtk.TextMark mar) { - // Weed out user movement for text selection changes - Gtk.TextIter start, end; - buffer.get_selection_bounds (out start, out end); - - if (start.equal (last_select_start_iter) && end.equal (last_select_end_iter)) { - return; - } - - last_select_start_iter.assign (start); - last_select_end_iter.assign (end); + private bool continue_selection_timer = false; + private uint selection_changed_timer = 0; + private void schedule_selection_changed_event () { + // Update spaces immediately to maintain previous behaviour update_draw_spaces (); if (selection_changed_timer != 0) { - Source.remove (selection_changed_timer); - selection_changed_timer = 0; + continue_selection_timer = true; + return; } - // Fire deselected immediately - if (start.equal (end)) { - deselected (); - // Don't fire signal till we think select movement is done - } else { - selection_changed_timer = Timeout.add (THROTTLE_MS, selection_changed_event); - } + selection_changed_timer = Timeout.add (SELECTION_CHANGE_THROTTLE_MS, () => { + if (continue_selection_timer) { + continue_selection_timer = false; + return Source.CONTINUE; + } - } + selection_changed_timer = 0; + Gtk.TextIter start, end; + var selected_text = ""; + if (buffer.get_selection_bounds (out start, out end)) { + selected_text = buffer.get_text (start, end, true); + } - bool selection_changed_event () { - Gtk.TextIter start, end; - bool selected = buffer.get_selection_bounds (out start, out end); - if (selected) { - var prev_selected_text = selected_text; - selected_text = buffer.get_text (start, end, true); if (selected_text != prev_selected_text) { - selection_changed (start, end); + selection_changed (selected_text, start, end); } - } else { - deselected (); - } - selection_changed_timer = 0; - return false; + prev_selected_text = selected_text; + return Source.REMOVE; + }); } uint refresh_diff_timeout_id = 0; diff --git a/src/codecore.deps b/src/dogfood_code_core.deps similarity index 80% rename from src/codecore.deps rename to src/dogfood_code_core.deps index dcfdbb4614..f218dc80db 100644 --- a/src/codecore.deps +++ b/src/dogfood_code_core.deps @@ -1,4 +1,4 @@ -codecore +dogfood_code_core gtksourceview-4 gee-0.8 gobject-2.0 diff --git a/src/meson.build b/src/meson.build index 08497a1100..b5d5a0d88f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,6 +1,6 @@ conf_data = configuration_data() -conf_data.set_quoted('PROJECT_NAME', meson.project_name()) -conf_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) +conf_data.set_quoted('PROJECT_NAME', install_name) +conf_data.set_quoted('GETTEXT_PACKAGE', install_name) conf_data.set_quoted('VERSION', meson.project_version()) conf_data.set_quoted('PREFIX', get_option('prefix')) conf_data.set_quoted('PLUGINDIR', pluginsdir) @@ -65,7 +65,7 @@ code_files = files( ) executable( - meson.project_name(), + install_name, code_files, code_resources, config_header, @@ -73,8 +73,8 @@ executable( install: true ) -codecore = library( - 'codecore', +dogfood_code_core = library( + 'dogfood_code_core', code_files, config_header, dependencies: dependencies, @@ -87,16 +87,16 @@ pkg = import('pkgconfig') pkg.generate( version: '0.1', - libraries: codecore, - description: 'elementary Code headers', - name: 'codecore', - filebase: 'codecore' + libraries: dogfood_code_core, + description: 'experimental Code headers', + name: 'dogfood_code_core', + filebase: 'dogfood_code_core' ) -install_data ('codecore.deps', install_dir: get_option('prefix') / get_option('datadir') / 'vala' / 'vapi') +install_data ('dogfood_code_core.deps', install_dir: get_option('prefix') / get_option('datadir') / 'vala' / 'vapi') -codecore_dep = declare_dependency( - link_with: codecore, +dogfood_code_core_dep = declare_dependency( + link_with: dogfood_code_core, dependencies: dependencies, include_directories: [include_directories('.')] )