├── po ├── LINGUAS ├── meson.build └── POTFILES ├── .proton.json ├── src ├── plugins │ └── meson.build ├── proton_core.deps ├── config.vala.in ├── proton.gresource.xml ├── widgets │ ├── meson.build │ ├── global-search │ │ ├── GlobalSearchResult.vala │ │ └── GlobalSearch.vala │ ├── Container.vala │ ├── terminal │ │ └── TerminalGridPage.vala │ ├── MultiPaned.vala │ ├── SortableBox.vala │ ├── BottomPanel.vala │ ├── Loadable.vala │ └── ide-grid │ │ ├── IdeGridPage.vala │ │ └── IdeGrid.vala ├── services │ ├── Core.vala │ ├── Settings.vala │ └── PluginManager.vala ├── utils │ ├── assert │ │ ├── assert.vala │ │ ├── assert.h │ │ └── assert.c │ ├── terminal │ │ └── terminal.vala │ ├── utils.vala │ └── git │ │ └── Cloner.vala ├── main.vala ├── application.vala ├── about_window.vala ├── preferences_window.vala ├── layouts │ ├── bottom_panel.ui │ ├── command_palette.ui │ ├── status_box.ui │ ├── editor_grid_page.ui │ └── global_search_result.ui ├── meson.build └── resources │ └── style.css ├── data ├── icons │ ├── hicolor │ │ ├── scalable │ │ │ ├── mimetypes │ │ │ │ ├── text-x-makefile-symbolic.svg │ │ │ │ ├── text-x-editorconfig-symbolic.svg │ │ │ │ ├── text-x-css.svg │ │ │ │ ├── text-x-css-symbolic.svg │ │ │ │ ├── text-x-xml-symbolic.svg │ │ │ │ ├── text-x-xml.svg │ │ │ │ ├── text-x-git.svg │ │ │ │ ├── text-x-git-symbolic.svg │ │ │ │ ├── text-x-c.svg │ │ │ │ ├── text-x-c-symbolic.svg │ │ │ │ ├── text-x-vala.svg │ │ │ │ ├── text-x-vala-symbolic.svg │ │ │ │ ├── text-x-meson.svg │ │ │ │ ├── text-x-meson-symbolic.svg │ │ │ │ ├── text-x-gitlab.svg │ │ │ │ ├── text-x-js.svg │ │ │ │ ├── text-x-js-symbolic.svg │ │ │ │ ├── text-x-cpp.svg │ │ │ │ ├── text-x-cpp-symbolic.svg │ │ │ │ ├── text-x-script2.svg │ │ │ │ ├── text-x-script2-symbolic.svg │ │ │ │ ├── text-x-gitlab-symbolic.svg │ │ │ │ └── text-x-editorconfig.svg │ │ │ └── actions │ │ │ │ ├── view-left-panel-symbolic.svg │ │ │ │ ├── view-right-panel-symbolic.svg │ │ │ │ ├── view-bottom-panel-symbolic.svg │ │ │ │ ├── view-split-vertical-symbolic.svg │ │ │ │ ├── view-split-horizontal-symbolic.svg │ │ │ │ └── proton-build-symbolic.svg │ │ └── render-symbolic.py │ └── meson.build ├── com.raggesilver.Proton.desktop.in ├── meson.build ├── com.raggesilver.Proton.appdata.xml.in ├── com.raggesilver.Proton.gschema.xml └── themes │ └── proton-dark.xml ├── .editorconfig ├── meson.build ├── .gitignore ├── .gitmodules ├── .gitlab-ci.yml ├── test.sh ├── TODO.md └── README.md /po/LINGUAS: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /po/meson.build: -------------------------------------------------------------------------------- 1 | i18n.gettext('proton', preset: 'glib') 2 | -------------------------------------------------------------------------------- /.proton.json: -------------------------------------------------------------------------------- 1 | { 2 | "buildsystem": "simple", 3 | "commands": [ "sh test.sh" ] 4 | } 5 | -------------------------------------------------------------------------------- /src/plugins/meson.build: -------------------------------------------------------------------------------- 1 | subdir('editorconfig') 2 | subdir('runner') 3 | subdir('autobracket') 4 | -------------------------------------------------------------------------------- /src/proton_core.deps: -------------------------------------------------------------------------------- 1 | gio-2.0 2 | gmodule-2.0 3 | vte-2.91 4 | gtk+-3.0 5 | gtksourceview-3.0 6 | marble 7 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-makefile-symbolic.svg: -------------------------------------------------------------------------------- 1 | /home/pqueiroz/Projects/proton/data/icons/hicolor/scalable/mimetypes/text-x-makefile.svg -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-editorconfig-symbolic.svg: -------------------------------------------------------------------------------- 1 | /home/pqueiroz/Projects/proton/data/icons/hicolor/scalable/mimetypes/text-x-editorconfig.svg -------------------------------------------------------------------------------- /po/POTFILES: -------------------------------------------------------------------------------- 1 | data/com.raggesilver.Proton.desktop.in 2 | data/com.raggesilver.Proton.appdata.xml.in 3 | data/com.raggesilver.Proton.gschema.xml 4 | src/window.ui 5 | src/main.vala 6 | src/window.vala 7 | 8 | -------------------------------------------------------------------------------- /data/com.raggesilver.Proton.desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Name=Proton 3 | Exec=proton 4 | Terminal=false 5 | Icon=com.raggesilver.Proton 6 | Type=Application 7 | Categories=GNOME;GTK;Development;IDE; 8 | Keywords=Build;Develop; 9 | StartupNotify=true 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | charset = utf-8 7 | trim_trailing_whitespace = true 8 | insert_final_newline = true 9 | 10 | [*.ui] 11 | indent_size = 2 12 | 13 | [Makefile] 14 | indent_style = tab 15 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('proton', ['c', 'vala'], 2 | version: '0.3.1', 3 | meson_version: '>= 0.49.0', 4 | ) 5 | 6 | i18n = import('i18n') 7 | 8 | subdir('data') 9 | subdir('src') 10 | subdir('po') 11 | 12 | meson.add_install_script('build-aux/meson/postinstall.py') 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | app/ 2 | app_build/ 3 | _build/ 4 | _native/ 5 | _native_build/ 6 | _proton_build/ 7 | *.*~ 8 | *test* 9 | \#*# 10 | 11 | Makefile 12 | 13 | .vscode 14 | .idea 15 | 16 | data/icons/hicolor/icons.gresource.xml 17 | 18 | .proton/ 19 | .flatpak-builder/ 20 | !test.sh 21 | repo/ 22 | *.flatpak 23 | -------------------------------------------------------------------------------- /src/config.vala.in: -------------------------------------------------------------------------------- 1 | namespace Proton.Constants 2 | { 3 | public const string GETTEXT_PACKAGE = @GETTEXT_PACKAGE@; 4 | public const string PROJECT_NAME = @PROJECT_NAME@; 5 | public const string VERSION = @VERSION@; 6 | public const string PLUGINDIR = @PLUGINDIR@; 7 | public const string INSTALL_PREFIX = @PREFIX@; 8 | public const string DATADIR = @DATADIR@; 9 | } 10 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/plugins/runner"] 2 | path = src/plugins/runner 3 | url = ../proton-runner-plugin 4 | [submodule "src/plugins/editorconfig"] 5 | path = src/plugins/editorconfig 6 | url = ../proton-editorconfig-plugin 7 | [submodule "data/templates"] 8 | path = data/templates 9 | url = ../proton-templates 10 | [submodule "src/plugins/autobracket"] 11 | path = src/plugins/autobracket 12 | url = ../proton-autobracket-plugin 13 | -------------------------------------------------------------------------------- /data/icons/meson.build: -------------------------------------------------------------------------------- 1 | icondir = join_paths(get_option('datadir'), 'icons/hicolor') 2 | pkgicondir = join_paths(get_option('datadir'), 'proton/icons/hicolor') 3 | 4 | install_subdir('hicolor/scalable', install_dir: pkgicondir) 5 | install_subdir('hicolor/16x16', install_dir: pkgicondir) 6 | install_subdir('hicolor/32x32', install_dir: pkgicondir) 7 | install_subdir('hicolor/48x48', install_dir: pkgicondir) 8 | install_subdir('hicolor/64x64', install_dir: pkgicondir) 9 | 10 | install_data(['hicolor/scalable/apps/com.raggesilver.Proton.svg'], 11 | install_dir: join_paths(icondir, 'scalable/apps')) 12 | 13 | -------------------------------------------------------------------------------- /src/proton.gresource.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | layouts/bottom_panel.ui 5 | layouts/command_palette.ui 6 | layouts/editor_grid_page.ui 7 | layouts/editor_search_box.ui 8 | layouts/editor_stack.ui 9 | layouts/global_search.ui 10 | layouts/global_search_result.ui 11 | layouts/open_window.ui 12 | layouts/preferences_window.ui 13 | layouts/proton_grid_stack.ui 14 | layouts/status_box.ui 15 | layouts/treeview_popover.ui 16 | layouts/window.ui 17 | resources/style.css 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/widgets/meson.build: -------------------------------------------------------------------------------- 1 | proton_sources += [ 2 | 'widgets/BottomPanel.vala', 3 | 'widgets/CommandPalette.vala', 4 | 'widgets/Container.vala', 5 | 'widgets/editor/Editor.vala', 6 | 'widgets/editor/EditorGridPage.vala', 7 | 'widgets/editor/EditorSearchBox.vala', 8 | 'widgets/global-search/GlobalSearch.vala', 9 | 'widgets/global-search/GlobalSearchResult.vala', 10 | 'widgets/ide-grid/IdeGrid.vala', 11 | 'widgets/ide-grid/IdeGridPage.vala', 12 | 'widgets/ide-grid/IdeGridStack.vala', 13 | 'widgets/Loadable.vala', 14 | 'widgets/MultiPaned.vala', 15 | 'widgets/SortableBox.vala', 16 | 'widgets/StatusBox.vala', 17 | 'widgets/terminal/Terminal.vala', 18 | 'widgets/terminal/TerminalGridPage.vala', 19 | 'widgets/terminal/TerminalTab.vala', 20 | 'widgets/TreeView.vala', 21 | ] 22 | -------------------------------------------------------------------------------- /src/services/Core.vala: -------------------------------------------------------------------------------- 1 | /* Core.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.Core : Object { 22 | } 23 | -------------------------------------------------------------------------------- /src/utils/assert/assert.vala: -------------------------------------------------------------------------------- 1 | /* assert.vapi 2 | * 3 | * Copyright 2020 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | namespace Proton 22 | { 23 | [CCode (cname="PROTON_ASSERT_", cheader_filename="assert.h")] 24 | extern bool assert_(bool expr) throws GLib.Error; 25 | } 26 | -------------------------------------------------------------------------------- /src/utils/assert/assert.h: -------------------------------------------------------------------------------- 1 | /* assert.h 2 | * 3 | * Copyright 2020 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | #pragma once 22 | 23 | #include 24 | 25 | typedef enum e_ProtonAssertionError 26 | { 27 | PROTON_ASSERTION_ERROR_ASSERT_ERROR 28 | } ProtonAssertionError; 29 | 30 | #define PROTON_ASSERTION_ERROR proton_assertion_error_quark() 31 | #define PROTON_ASSERT_(expr, err) \ 32 | proton_assert_((expr), "Assertion " #expr " failed", err) 33 | 34 | GQuark proton_assertion_error_quark(void); 35 | gboolean proton_assert_(gboolean expr, gchar *msg, GError **error); 36 | -------------------------------------------------------------------------------- /src/main.vala: -------------------------------------------------------------------------------- 1 | /* main.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | */ 18 | 19 | int main (string[] args) 20 | { 21 | var app = new Proton.Application(); 22 | 23 | app.activate.connect(() => { 24 | var win = new Proton.OpenWindow(app); 25 | win.show(); 26 | }); 27 | 28 | app.open.connect((files, hint) => { 29 | 30 | if (files.length != 1) 31 | { 32 | error("Provide one directory"); 33 | } 34 | 35 | var f = new Proton.File(files[0].get_path()); 36 | 37 | if (!f.is_directory) 38 | { 39 | error("Provide one directory"); 40 | } 41 | 42 | var win = new Proton.Window(app, f); 43 | win.show(); 44 | }); 45 | 46 | return app.run(args); 47 | } 48 | -------------------------------------------------------------------------------- /data/meson.build: -------------------------------------------------------------------------------- 1 | subdir('icons') 2 | 3 | install_subdir('themes', 4 | install_dir: join_paths(get_option('datadir'), 'proton')) 5 | 6 | subdir('templates') 7 | 8 | desktop_file = i18n.merge_file( 9 | input: 'com.raggesilver.Proton.desktop.in', 10 | output: 'com.raggesilver.Proton.desktop', 11 | type: 'desktop', 12 | po_dir: '../po', 13 | install: true, 14 | install_dir: join_paths(get_option('datadir'), 'applications') 15 | ) 16 | 17 | desktop_utils = find_program('desktop-file-validate', required: false) 18 | if desktop_utils.found() 19 | test('Validate desktop file', desktop_utils, 20 | args: [desktop_file] 21 | ) 22 | endif 23 | 24 | appstream_file = i18n.merge_file( 25 | input: 'com.raggesilver.Proton.appdata.xml.in', 26 | output: 'com.raggesilver.Proton.appdata.xml', 27 | po_dir: '../po', 28 | install: true, 29 | install_dir: join_paths(get_option('datadir'), 'metainfo') 30 | ) 31 | 32 | appstream_util = find_program('appstream-util', required: false) 33 | if appstream_util.found() 34 | test('Validate appstream file', appstream_util, 35 | args: ['validate', appstream_file] 36 | ) 37 | endif 38 | 39 | install_data('com.raggesilver.Proton.gschema.xml', 40 | install_dir: join_paths(get_option('datadir'), 'glib-2.0/schemas') 41 | ) 42 | 43 | compile_schemas = find_program('glib-compile-schemas', required: false) 44 | if compile_schemas.found() 45 | test('Validate schema file', compile_schemas, 46 | args: ['--strict', '--dry-run', meson.current_source_dir()] 47 | ) 48 | endif 49 | -------------------------------------------------------------------------------- /src/utils/assert/assert.c: -------------------------------------------------------------------------------- 1 | /* assert.c 2 | * 3 | * Copyright 2020 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | #include "assert.h" 22 | 23 | #define PROTON_ASSERTION_ERROR proton_assertion_error_quark() 24 | 25 | GQuark proton_assertion_error_quark(void) 26 | { 27 | return g_quark_from_static_string("assertion-error-quark"); 28 | } 29 | 30 | gboolean proton_assert_(gboolean expr, gchar *msg, GError **error) 31 | { 32 | GError *err; 33 | 34 | if (!expr) 35 | { 36 | err = g_error_new_literal(PROTON_ASSERTION_ERROR, 37 | PROTON_ASSERTION_ERROR_ASSERT_ERROR, 38 | msg); 39 | g_propagate_error(error, err); 40 | return (FALSE); 41 | } 42 | return (TRUE); 43 | } 44 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - build 3 | - deploy 4 | 5 | variables: 6 | BUILD_DIR: _build 7 | CONFIG_CMD: meson --buildtype=debug build 8 | BUILD_CMD: ninja -v -C $BUILD_DIR 9 | INSTALL_CMD: ninja -v -C $BUILD_DIR install 10 | 11 | APP_ID: com.raggesilver.Proton 12 | BUNDLE: proton.flatpak 13 | FLATPAK_MODULE: proton 14 | GIT_SUBMODULE_STRATEGY: normal 15 | MANIFEST_PATH: com.raggesilver.Proton.json 16 | RUNTIME_REPO: "https://sdk.gnome.org/gnome-nightly.flatpakrepo" 17 | 18 | build: 19 | stage: build 20 | image: 'registry.gitlab.gnome.org/gnome/gnome-runtime-images/gnome:3.34' 21 | script: 22 | - flatpak-builder --stop-at=${FLATPAK_MODULE} app ${MANIFEST_PATH} 23 | - flatpak-builder --run app ${MANIFEST_PATH} meson --prefix=/app ${MESON_ARGS} _build 24 | - flatpak-builder --run app ${MANIFEST_PATH} ninja -C _build install 25 | - flatpak-builder --finish-only --repo=repo app ${MANIFEST_PATH} 26 | - flatpak build-export repo app 27 | - flatpak build-bundle repo ${BUNDLE} ${APP_ID} 28 | artifacts: 29 | paths: 30 | - "${BUNDLE}" 31 | expire_in: 5 days 32 | cache: 33 | key: "flatpak" 34 | paths: 35 | - .flatpak-builder/downloads/ 36 | - .flatpak-builder/git/ 37 | 38 | deploy: 39 | stage: deploy 40 | dependencies: 41 | - build 42 | script: 43 | - echo "Generating Flatpak" 44 | artifacts: 45 | paths: 46 | - "${BUNDLE}" 47 | environment: 48 | name: deploy/$CI_COMMIT_REF_NAME 49 | url: https://gnome.com/$CI_PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/raw/${BUNDLE} 50 | -------------------------------------------------------------------------------- /src/widgets/global-search/GlobalSearchResult.vala: -------------------------------------------------------------------------------- 1 | /* GlobalSearchResult.vala 2 | * 3 | * Copyright 2020 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | [GtkTemplate (ui = "/com/raggesilver/Proton/layouts/global_search_result.ui")] 22 | public class Proton.GlobalSearchResult : Gtk.Box 23 | { 24 | [GtkChild] private Gtk.Revealer revealer; 25 | 26 | public GlobalSearchResult() {} 27 | 28 | [GtkCallback] 29 | private void on_replace_button_clicked() {} 30 | 31 | [GtkCallback] 32 | private void on_remove_button_clicked() {} 33 | 34 | [GtkCallback] 35 | private bool on_focus_in_event(Gdk.EventFocus e) 36 | { 37 | (void)e; 38 | this.revealer.set_reveal_child(true); 39 | return (false); 40 | } 41 | 42 | [GtkCallback] 43 | private bool on_focus_out_event(Gdk.EventFocus e) 44 | { 45 | (void)e; 46 | this.revealer.set_reveal_child(false); 47 | return (false); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | MODULE="proton" 4 | MANIFEST="com.raggesilver.Proton.json" 5 | APP_ID="com.raggesilver.Proton" 6 | 7 | run=1 8 | 9 | if [[ $# -ge 1 ]]; then 10 | 11 | case $1 in 12 | 13 | "update") 14 | echo "Run update"; 15 | flatpak-builder --ccache --force-clean --download-only --stop-at=$MODULE app $MANIFEST 16 | flatpak-builder --ccache --force-clean --disable-updates --disable-download --stop-at=$MODULE app $MANIFEST 17 | exit 0; 18 | ;; 19 | 20 | "update-soft") 21 | echo "Run soft update"; 22 | flatpak-builder --force-clean --ccache --stop-at=$MODULE app $MANIFEST 23 | exit 0; 24 | ;; 25 | 26 | "--no-run") 27 | run=0 28 | ;; 29 | 30 | "export") 31 | echo "Run export"; 32 | sh ${BASH_SOURCE[0]} --no-run 33 | flatpak-builder --finish-only --repo=repo app $MANIFEST 34 | flatpak build-export repo app 35 | flatpak build-bundle repo "${MODULE}.flatpak" $APP_ID 36 | exit 0; 37 | ;; 38 | 39 | *) 40 | echo "Invalid option '$1'"; 41 | exit 1; 42 | ;; 43 | esac 44 | fi 45 | 46 | if [ ! -d "app" ]; then 47 | flatpak-builder --stop-at=$MODULE app $MANIFEST || exit $? 48 | fi 49 | 50 | flatpak-builder --run app $MANIFEST meson --prefix=/app app_build || exit $? 51 | 52 | flatpak-builder --run app $MANIFEST ninja -C app_build || exit $? 53 | flatpak-builder --run app $MANIFEST ninja -C app_build install || exit $? 54 | 55 | if [[ $run -eq 1 ]]; then 56 | flatpak-builder --run app $MANIFEST $MODULE || exit $? 57 | fi 58 | -------------------------------------------------------------------------------- /src/application.vala: -------------------------------------------------------------------------------- 1 | /* application.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | namespace Proton 22 | { 23 | public Settings settings; 24 | } 25 | 26 | public class Proton.Application : Gtk.Application 27 | { 28 | construct 29 | { 30 | flags |= ApplicationFlags.HANDLES_OPEN; 31 | flags |= ApplicationFlags.NON_UNIQUE; 32 | // TODO man up and use command line 33 | // flags |= ApplicationFlags.HANDLES_COMMAND_LINE; 34 | 35 | application_id = "com.raggesilver.Proton"; 36 | } 37 | 38 | public Application() 39 | { 40 | settings = Proton.Settings.get_instance(); 41 | } 42 | 43 | // TODO: If Application is now Public then instance is no longer necessary 44 | public static Application _instance = null; 45 | public static Application instance { 46 | get { 47 | if (_instance == null) 48 | _instance = new Application(); 49 | return _instance; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | # TODO 2 | 3 | ## Todos 4 | 1. Right click popover on `TreeView` 5 | 3. `PreferencesWindow` (WIP [src/preferences_window.vala](https://gitlab.com/raggesilver-proton/proton/blob/master/src/preferences_window.vala)) 6 | 4. Plugins: 42, git, ~~run~~ -> runner (WIP [proton-runner-plugin](https://gitlab.com/raggesilver-proton/proton-runner-plugin)) 7 | 6. Finish `OpenWindow`[^1] 8 | 9 | - ~~Finish terminal widget~~ Fair base widget for terminal use. Needs improvement 10 | - ~~Command palette~~ Works reasonably well 11 | - ~~File modified characted on the window title (e.g "Proton - filename.c •")~~ 12 | - ~~Prevent app quiting when modified editors are still open~~ 13 | - ~~TreeView updates~~ 14 | 15 | ## CommandPalette 16 | 17 | Apart from actually creating a proper command palette, finding files needs a 18 | rework. The issue is that it currently finds compiled files and the quick fix 19 | `find ... -exec grep -Iq . {} \; -print` makes the command take way longer to 20 | index the files, making it unusable. 21 | 22 | A possible way to fix this is by indexing the text files as soon as the IDE 23 | starts and reindexing once there is a change in the folder. 24 | 25 | Note: the command `file ` outputs information of the given file. Valid 26 | text files contain ASCII and/or {'text', 'empty'}. 27 | 28 | Note 2: having the option to manually set exclude patterns for indexing and 29 | using `.gitignore` would be good. 30 | 31 | ## OpenWindow 32 | 33 | Since [58ba5efb](https://gitlab.com/raggesilver-proton/proton/commit/58ba5efb6893178f9514a3d381919d6b58915001) 34 | I began working on cloning existing repos from a remote location. That still 35 | has a lot of bugs which may cause the entire program to crash. 36 | 37 | Templates should also be created. Templating needs design and further planning 38 | to maybe load templates from a file. 39 | -------------------------------------------------------------------------------- /src/about_window.vala: -------------------------------------------------------------------------------- 1 | /* about_window.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.AboutWindow : Gtk.AboutDialog 22 | { 23 | public AboutWindow(Window win) 24 | { 25 | this.set_destroy_with_parent(true); 26 | this.set_transient_for(win); 27 | this.set_modal(true); 28 | 29 | this.authors = { "Paulo Queiroz" }; 30 | this.translator_credits = null; 31 | 32 | this.program_name = "Proton"; 33 | this.comments = "Proton, because electron is not enough."; 34 | this.copyright = "Copyright 2019 Paulo Queiroz"; 35 | this.version = Constants.VERSION; 36 | 37 | this.website = "https://gitlab.com/raggesilver-proton/proton"; 38 | this.website_label = "Gitlab repo"; 39 | 40 | this.license_type = Gtk.License.GPL_3_0; 41 | 42 | this.logo_icon_name = "com.raggesilver.Proton"; 43 | 44 | this.response.connect((res) => { 45 | this.destroy(); 46 | }); 47 | 48 | this.get_header_bar().get_style_context().add_class("clean"); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/widgets/Container.vala: -------------------------------------------------------------------------------- 1 | /* Container.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.Container : Gtk.Stack { 22 | 23 | public Gtk.Widget widget; 24 | private Gtk.Spinner spinner; 25 | 26 | private bool _working { get; set; default = false; } 27 | public bool working { get { return _working; } } 28 | 29 | public Container(Gtk.Widget w, bool working = false) { 30 | widget = w; 31 | _working = working; 32 | 33 | spinner = new Gtk.Spinner (); 34 | spinner.start (); 35 | spinner.show (); 36 | 37 | add_named (widget, "widget"); 38 | add_named (spinner, "spinner"); 39 | 40 | set_working (_working); 41 | show (); 42 | } 43 | 44 | public Container.with_scroller (Gtk.Widget w, bool working = false) { 45 | var scroll = new Gtk.ScrolledWindow (null, null); 46 | scroll.show (); 47 | scroll.add (w); 48 | this(scroll, working); 49 | } 50 | 51 | public void set_working(bool working) { 52 | _working = working; 53 | set_visible_child_name (_working ? "spinner" : "widget"); 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /src/widgets/terminal/TerminalGridPage.vala: -------------------------------------------------------------------------------- 1 | /* TerminalGridPage.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.TerminalGridPage : IdeGridPage 22 | { 23 | public Terminal terminal { get; protected set; } 24 | unowned Window win; 25 | 26 | public TerminalGridPage(Window _win) 27 | { 28 | win = _win; 29 | 30 | terminal = new Terminal(win); 31 | var scrolled = new Gtk.ScrolledWindow(null, null); 32 | scrolled.set_policy(Gtk.PolicyType.EXTERNAL, Gtk.PolicyType.AUTOMATIC); 33 | scrolled.add(terminal); 34 | 35 | pack_start(scrolled, true, true, 0); 36 | show_all(); 37 | 38 | title = "Terminal %u".printf(terminal.id); 39 | 40 | // FIXME: create a way to change the title only on IdeGridStack.titlebar 41 | // and keep the initial on IdeGridStack.popover 42 | 43 | // terminal.window_title_changed.connect(() => { 44 | // title = terminal.window_title; 45 | // }); 46 | 47 | terminal.focus_in_event.connect((e) => { 48 | focused(); 49 | return (false); 50 | }); 51 | 52 | terminal.child_exited.connect((status) => { 53 | this.destroy(); 54 | }); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/widgets/MultiPaned.vala: -------------------------------------------------------------------------------- 1 | /* MultiPaned.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.MultiPaned : Dazzle.MultiPaned 22 | { 23 | public MultiPaned(Gtk.Orientation orientation) 24 | { 25 | Object(orientation: orientation); 26 | } 27 | 28 | public override void add(Gtk.Widget widget) 29 | { 30 | base.add(widget); 31 | // var sizes = new Array(); 32 | var _children = new Array(); 33 | 34 | // var total_size = 0; 35 | 36 | forall((w) => { 37 | _children.append_val(w); 38 | // float sz = (orientation == Gtk.Orientation.HORIZONTAL) ? 39 | // w.get_allocated_width() : 40 | // w.get_allocated_height(); 41 | // sizes.append_val(sz); 42 | // total_size += sz; 43 | }); 44 | 45 | // int sz = (orientation == Gtk.Orientation.HORIZONTAL) ? 46 | // get_allocated_width() : get_allocated_height(); 47 | 48 | // int ns = (int) (sz / _children.length); 49 | foreach (var c in _children.data) 50 | { 51 | if (orientation == Gtk.Orientation.HORIZONTAL) 52 | c.set_hexpand(true); 53 | else 54 | c.set_vexpand(true); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/widgets/SortableBox.vala: -------------------------------------------------------------------------------- 1 | /* SortableBox.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.SortableBox : Gtk.Box 22 | { 23 | public delegate int PCompareFunction(void *a, void *b); 24 | public delegate SortableBox? PIsSortableFunction(void *a); 25 | 26 | public SortableBox(Gtk.Orientation orientation, int spacing) 27 | { 28 | Object(orientation: orientation, 29 | spacing: spacing); 30 | } 31 | 32 | public void sort(PCompareFunction comp, 33 | PIsSortableFunction? is_sort, 34 | bool do_recursion = true) 35 | { 36 | #if DEBUG_SORTABLE_BOX 37 | var t = new Timer(); 38 | t.start(); 39 | #endif 40 | 41 | var lst = get_children(); 42 | var len = lst.length(); 43 | 44 | if (len == 0) 45 | return ; 46 | 47 | lst.sort((CompareFunc)comp); 48 | 49 | for (uint i = 0; i < len; i++) 50 | reorder_child(lst.nth_data(i), (int)i); 51 | 52 | #if DEBUG_SORTABLE_BOX 53 | t.stop(); 54 | ulong mc = 0; 55 | t.elapsed(out mc); 56 | debug("[SortableBox] Sort ended in %lu microseconds", mc); 57 | #endif 58 | 59 | if (is_sort != null && do_recursion) 60 | { 61 | for (uint i = 0; i < len; i++) 62 | { 63 | var s = is_sort(lst.nth_data(i)); 64 | if (s != null) 65 | s.sort(comp, is_sort); 66 | } 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-css.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-css-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /src/widgets/BottomPanel.vala: -------------------------------------------------------------------------------- 1 | /* BottomPanel.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.BottomPanelTab : Object 22 | { 23 | public signal void focus_tab(); 24 | 25 | public Gtk.Widget content; 26 | public Gtk.Widget? aux_content; 27 | 28 | public bool enabled = true; 29 | public string name; 30 | public string title; 31 | } 32 | 33 | [GtkTemplate (ui="/com/raggesilver/Proton/layouts/bottom_panel.ui")] 34 | public class Proton.BottomPanel : Gtk.Box 35 | { 36 | [GtkChild] Gtk.Stack stack; 37 | [GtkChild] Gtk.Stack aux_stack; 38 | 39 | private Window win; 40 | 41 | public BottomPanel(Window _win) 42 | { 43 | this.win = _win; 44 | 45 | this.stack.notify["visible-child-name"].connect(this.on_switched); 46 | } 47 | 48 | public bool add_tab(BottomPanelTab tab) 49 | { 50 | if (stack.get_child_by_name(tab.name) == null) 51 | { 52 | stack.add_titled(tab.content, tab.name, tab.title); 53 | 54 | tab.focus_tab.connect(() => { 55 | stack.set_visible_child(tab.content); 56 | }); 57 | 58 | if (tab.aux_content != null) 59 | aux_stack.add_titled(tab.aux_content, tab.name, tab.title); 60 | 61 | return (true); 62 | } 63 | warning("A tab with named %s alread exists", tab.name); 64 | return (false); 65 | } 66 | 67 | void on_switched() 68 | { 69 | string? stack_vc = stack.visible_child_name; 70 | var _child = (stack_vc != null) ? 71 | this.aux_stack.get_child_by_name(stack_vc) : null; 72 | 73 | if (_child != null) 74 | aux_stack.set_visible_child(_child); 75 | else 76 | aux_stack.set_visible_child_name("empty"); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/services/Settings.vala: -------------------------------------------------------------------------------- 1 | /* Settings.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.Settings : Marble.Settings 22 | { 23 | private static Proton.Settings? instance = null; 24 | 25 | public bool dark_mode { get; set; } 26 | public bool transparency { get; set; } 27 | public int width { get; set; } 28 | public int height { get; set; } 29 | public int pos_x { get; set; } 30 | public int pos_y { get; set; } 31 | public string[] recent_projects { get; set; } 32 | public int bottom_panel_height { get; set; } 33 | public int left_panel_width { get; set; } 34 | public bool bottom_panel_visible { get; set; } 35 | public bool left_panel_visible { get; set; } 36 | 37 | private Settings() 38 | { 39 | base("com.raggesilver.Proton"); 40 | } 41 | 42 | /* 43 | * I decided it is better to only have one instance of the settings class 44 | * because all project related settings should be stored in .proton/ and IDE 45 | * customizations such as theme and panels visibility (things that shouldn't 46 | * change on multiple windows at the same time) should only be saved on exit 47 | */ 48 | 49 | public static Proton.Settings get_instance() 50 | { 51 | if (instance == null) 52 | instance = new Proton.Settings(); 53 | return instance; 54 | } 55 | 56 | public void add_recent(string s) 57 | { 58 | string[] _recent = {}; 59 | _recent += s; 60 | foreach (var item in recent_projects) 61 | { 62 | if (!(item in _recent)) 63 | _recent += item; 64 | if (_recent.length > 4) 65 | break ; 66 | } 67 | recent_projects = _recent; 68 | } 69 | } 70 | 71 | -------------------------------------------------------------------------------- /src/widgets/Loadable.vala: -------------------------------------------------------------------------------- 1 | /* Loadable.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.Loadable : Gtk.Overlay 22 | { 23 | public bool loading { get; set; default = false; } 24 | public T content { get; set; } 25 | 26 | Gtk.Spinner spinner; 27 | 28 | public Loadable(T content) 29 | { 30 | Object(content: content); 31 | 32 | spinner = new Gtk.Spinner(); 33 | spinner.start(); 34 | 35 | add_overlay(spinner); 36 | set_overlay_pass_through(spinner, false); 37 | 38 | add(content as Gtk.Widget); 39 | 40 | notify["loading"].connect(loading_changed); 41 | 42 | get_style_context().add_class("loadable"); 43 | } 44 | 45 | void loading_changed() 46 | { 47 | spinner.set_visible(loading); 48 | } 49 | } 50 | 51 | public class Proton.Sortable : Proton.Loadable 52 | { 53 | public delegate int PCompareFunction(void *a, void *b); 54 | public delegate SortableBox? PIsSortableFunction(void *a); 55 | 56 | public Sortable(Gtk.Orientation orientation, int spacing) 57 | { 58 | var _content = new SortableBox(orientation, spacing); 59 | 60 | base(_content); 61 | 62 | content.show(); 63 | show(); 64 | } 65 | 66 | public void sort(PCompareFunction comp, 67 | PIsSortableFunction? is_sort, 68 | bool do_recursion = true) 69 | { 70 | content.sort(comp, is_sort, do_recursion); 71 | } 72 | 73 | public void pack_start(Gtk.Widget w, bool expand, bool fill, int spacing) 74 | { 75 | content.pack_start(w, expand, fill, spacing); 76 | } 77 | 78 | public void pack_end(Gtk.Widget w, bool expand, bool fill, int spacing) 79 | { 80 | content.pack_end(w, expand, fill, spacing); 81 | } 82 | 83 | public new void add(Gtk.Widget w) 84 | { 85 | content.add(w); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /data/icons/hicolor/render-symbolic.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import os 4 | import shutil 5 | import sys 6 | 7 | _resources = {} 8 | _aliases = {} 9 | _ignore = ( 10 | 'com.raggesilver.Proton.svg', 11 | 'com.raggesilver.Proton-symbolic.svg', 12 | ) 13 | 14 | def addResource(directory, name): 15 | if directory not in _resources: 16 | _resources[directory] = [] 17 | _resources[directory].append(name) 18 | 19 | def gtkEncodeSymbolicSvg(outdir, path, size): 20 | if not os.path.isdir(outdir): 21 | os.makedirs(outdir) 22 | cmd = 'gtk-encode-symbolic-svg -o "%s" "%s" %dx%d' % (outdir, path, size, size) 23 | print(cmd) 24 | os.system(cmd) 25 | 26 | def sort(l): 27 | l = list(l) 28 | l.sort() 29 | return l 30 | 31 | # These just need to be aliased properly 32 | # for name in os.listdir('scalable/patterns'): 33 | # _aliases[os.path.join('scalable/actions', name)] = os.path.join('scalable/patterns', name) 34 | 35 | # These need to be scaled as symbolic icons into 36 | # 16 and their 2x and 3x counterparts 37 | for dirname in ('actions', 'mimetypes'): 38 | for name in sort(os.listdir(os.path.join('scalable', dirname))): 39 | for size in (16, 32, 48, 64): 40 | outdir = '%dx%d/%s' % (size, size, dirname) 41 | path = os.path.join('scalable', dirname, name) 42 | gtkEncodeSymbolicSvg(outdir, path, size) 43 | symbolic_name = name[:-4] + '.symbolic.png' 44 | addResource(outdir, symbolic_name) 45 | 46 | # We need larger versions for apps 47 | for dirname in ('apps',): 48 | for name in sort(os.listdir(os.path.join('scalable', dirname))): 49 | if name in _ignore: 50 | continue 51 | for size in (16, 32, 48, 128, 256, 512): 52 | outdir = '%dx%d/%s' % (size, size, dirname) 53 | path = os.path.join('scalable', dirname, name) 54 | gtkEncodeSymbolicSvg(outdir, path, size) 55 | symbolic_name = name[:-4] + '.symbolic.png' 56 | addResource(outdir, symbolic_name) 57 | 58 | # Now generate our updated .gresources.xml 59 | with open("icons.gresource.xml", "w") as stream: 60 | stream.write(''' 61 | 62 | 63 | 64 | ''') 65 | #for dirname, names in _resources.items(): 66 | # names.sort() 67 | # for name in names: 68 | # stream.write(' %s/%s\n' % (dirname, name)) 69 | for alias in sort(_aliases.keys()): 70 | name = _aliases[alias] 71 | stream.write(' %s\n' % (alias, name)) 72 | stream.write(''' 73 | 74 | ''') 75 | 76 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-left-panel-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-right-panel-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-bottom-panel-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-split-vertical-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 63 | 68 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/view-split-horizontal-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 63 | 68 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /src/widgets/ide-grid/IdeGridPage.vala: -------------------------------------------------------------------------------- 1 | /* IdeGridPage.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | /* 22 | ** Widget that will be added to IdeGridStack.popover. 23 | */ 24 | 25 | public class Proton.IdeGridPagePopEntry : Gtk.ListBoxRow 26 | { 27 | public Gtk.Label label { get; private set; } 28 | public Gtk.Button close_button { get; private set; } 29 | public IdeGridPage page { get; private set; } 30 | 31 | public IdeGridPagePopEntry(IdeGridPage _page) 32 | { 33 | page = _page; 34 | label = new Gtk.Label(null); 35 | page.notify["title"].connect(() => { 36 | label.label = page.title; 37 | }); 38 | close_button = new Gtk.Button.from_icon_name("window-close-symbolic", 39 | Gtk.IconSize.MENU); 40 | close_button.set_relief(Gtk.ReliefStyle.NONE); 41 | close_button.get_style_context().add_class("close"); 42 | 43 | var b = new Gtk.Box(Gtk.Orientation.HORIZONTAL, 0); 44 | 45 | b.pack_start(label, true, true, 0); 46 | b.pack_end(close_button, false, false, 0); 47 | 48 | add(b); 49 | 50 | show_all(); 51 | } 52 | } 53 | 54 | public abstract class Proton.IdeGridPage : Gtk.Box 55 | { 56 | public signal void focused(); 57 | public signal void style_changed(string? bg, string? fg); 58 | 59 | public string? bg { get; set; default = null; } 60 | public string? fg { get; set; default = null; } 61 | 62 | public string title { get; set; } 63 | public IdeGridPagePopEntry pop_entry { get; private set; } 64 | 65 | construct 66 | { 67 | pop_entry = new IdeGridPagePopEntry(this); 68 | pop_entry.close_button.clicked.connect(() => { 69 | destroy(); 70 | }); 71 | notify["bg"].connect(() => { 72 | style_changed(bg, fg); 73 | }); 74 | notify["fg"].connect(() => { 75 | style_changed(bg, fg); 76 | }); 77 | } 78 | 79 | protected IdeGridPage() 80 | { 81 | Object(orientation: Gtk.Orientation.VERTICAL); 82 | } 83 | 84 | public override void destroy() 85 | { 86 | pop_entry.destroy(); 87 | base.destroy(); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-xml-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 63 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-xml.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 63 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-git.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 62 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/preferences_window.vala: -------------------------------------------------------------------------------- 1 | /* preferences_window.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | [GtkTemplate (ui="/com/raggesilver/Proton/layouts/preferences_window.ui")] 22 | public class Proton.PreferencesWindow : Gtk.ApplicationWindow 23 | { 24 | [GtkChild] Gtk.Box color_scheme_box; 25 | [GtkChild] Gtk.FontButton font_button; 26 | [GtkChild] Gtk.Switch dark_mode_switch; 27 | [GtkChild] Gtk.Switch transparency_switch; 28 | [GtkChild] Gtk.Switch word_wrap_switch; 29 | 30 | private weak Window window; 31 | private Settings settings; 32 | private EditorSettings ed_settings; 33 | 34 | public PreferencesWindow(Window _win) 35 | { 36 | Object(application: _win.application); 37 | 38 | this.window = _win; 39 | this.settings = Settings.get_instance(); 40 | this.ed_settings = EditorSettings.get_instance(); 41 | 42 | this.set_transient_for(_win); 43 | 44 | var c = new Gtk.SourceStyleSchemeChooserButton(); 45 | c.set_style_scheme(Gtk.SourceStyleSchemeManager.get_default() 46 | .get_scheme(this.ed_settings.style_id)); 47 | 48 | c.notify["style-scheme"].connect(() => { 49 | this.ed_settings.style_id = c.style_scheme.id; 50 | }); 51 | 52 | color_scheme_box.add(c); 53 | color_scheme_box.show_all(); 54 | 55 | font_button.font = this.ed_settings.font_family; 56 | 57 | this.settings.schema.bind("dark-mode", this.dark_mode_switch, 58 | "active", SettingsBindFlags.DEFAULT); 59 | this.dark_mode_switch.active = this.settings.dark_mode; 60 | 61 | this.settings.schema.bind("transparency", this.transparency_switch, 62 | "active", SettingsBindFlags.DEFAULT); 63 | this.transparency_switch.active = this.settings.transparency; 64 | 65 | this.ed_settings.schema.bind("word-wrap", this.word_wrap_switch, 66 | "active", SettingsBindFlags.DEFAULT); 67 | this.word_wrap_switch.active = this.ed_settings.word_wrap; 68 | } 69 | 70 | [GtkCallback] 71 | void on_font_set() 72 | { 73 | debug("Font set '%s'", font_button.font); 74 | EditorSettings.get_instance().font_family = font_button.font; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-git-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 62 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-c.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 61 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /data/com.raggesilver.Proton.appdata.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | com.raggesilver.Proton.desktop 4 | CC0-1.0 5 | GPL-3.0-or-later 6 | Proton 7 | A multipurpose IDE for Linux 8 | Paulo Queiroz 9 | 10 | 11 |

Proton is a multipurpose IDE for Linux.

12 |
13 | 14 | 15 | 16 | Quickly open or create new projects 17 | https://imgur.com/62uOokF.png 18 | 19 | 20 | 21 | com.raggesilver.Proton.desktop 22 | https://gitlab.com/raggesilver-proton/proton 23 | https://gitlab.com/raggesilver-proton/proton/issues 24 | 25 | 26 | none 27 | none 28 | none 29 | none 30 | none 31 | none 32 | none 33 | none 34 | none 35 | none 36 | none 37 | none 38 | none 39 | none 40 | none 41 | none 42 | none 43 | none 44 | none 45 | none 46 | none 47 | none 48 | none 49 | none 50 | none 51 | none 52 | none 53 | 54 | 55 |
56 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-c-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 61 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
2 |

3 | Proton 4 |

5 |

A soon-to-be IDE

6 |

7 | 8 | Build Status 9 | 10 | 11 | Proton on Patreon 12 | 13 |

14 |

15 | Install • 16 | Features • 17 | License 18 |

19 |
20 | 21 | ![Preview](https://imgur.com/VpePB31.png) 22 | 23 | ## Features 24 | - Integrated terminal 25 | - Plugin system (all [../proton-*-plugin](https://gitlab.com/raggesilver-proton/) are core plugins) 26 | - Overlay command palette + file discover 27 | - [Build system](https://gitlab.com/raggesilver-proton/proton-runner-plugin) 28 | - New project [templates](https://gitlab.com/raggesilver-proton/proton-templates) 29 | - Clone existing projects from a Git repo 30 | 31 | ## Install 32 | 33 | **Download** 34 | 35 | [Flatpak](https://gitlab.com/raggesilver-proton/proton/-/jobs/artifacts/master/raw/proton.flatpak?job=deploy) • [Zip](https://gitlab.com/raggesilver-proton/proton/-/jobs/artifacts/master/download?job=deploy) 36 | 37 | *Note: these two links might not work if the latest pipeline failed/is still running* 38 | 39 | **Flathub** 40 | 41 | > Flathub releases will be available once Proton hits version 1.0.0. 42 | 43 | ## Compile 44 | 45 | > Proton can be run on GNOME Builder. If you have Proton 0.1.8+ you can also 46 | > run Proton on Proton 😜️. (for either one just press play and behold magic) 47 | 48 | **Flatpak from source** 49 | 50 | ```bash 51 | # Clone the repo 52 | git clone --recursive https://gitlab.com/raggesilver-proton/proton 53 | # cd into the repo 54 | cd proton 55 | # Assuming you have both flatpak and flatpak-builder installed 56 | # test.sh has a few useful scripts that will build and install proton as a 57 | # flatpak locally on ./app_build and ./app 58 | sh test.sh 59 | # You can also 60 | # sh test.sh [command] 61 | # 62 | # update - update all flatpak dependencies 63 | # export - export proton as a flatpak. Generates ./proton.flatpak and ./repo 64 | ``` 65 | 66 | **Regular from source (unsupported)** 67 | 68 | ```bash 69 | # Clone the repo 70 | git clone --recursive https://gitlab.com/raggesilver-proton/proton 71 | # cd into the repo 72 | cd proton 73 | meson _build 74 | ninja -C _build 75 | # sudo 76 | ninja -C _build install 77 | ``` 78 | 79 | ## Gallery 80 | 81 | > These pictures are rarely updated (might be outdated) 82 | 83 | | Welcome window | Preferences window | 84 | | -------------- | ------------------ | 85 | | ![](https://imgur.com/ezTDdnt.png) | ![](https://imgur.com/DOun2WI.png) | 86 | 87 | ## Credits 88 | 89 | Code derived/based on other projects is properly attributed on each file. 90 | 91 | 92 | -------------------------------------------------------------------------------- /src/utils/terminal/terminal.vala: -------------------------------------------------------------------------------- 1 | /* terminal.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | namespace Proton 22 | { 23 | /* fp_guess_shell 24 | * 25 | * Copyright 2019 Christian Hergert 26 | * 27 | * The following function is a derivative work of the code from 28 | * https://gitlab.gnome.org/chergert/flatterm which is licensed under the 29 | * Apache License, Version 2.0 , at your option. This file may not 31 | * be copied, modified, or distributed except according to those terms. 32 | * 33 | * SPDX-License-Identifier: (MIT OR Apache-2.0) 34 | */ 35 | public string? fp_guess_shell(Cancellable? cancellable = null) throws Error 36 | { 37 | if (!is_flatpak()) 38 | return (Vte.get_user_shell()); 39 | 40 | string[] argv = { "flatpak-spawn", "--host", "getent", "passwd", 41 | Environment.get_user_name() }; 42 | 43 | var launcher = new GLib.SubprocessLauncher( 44 | SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_SILENCE 45 | ); 46 | 47 | launcher.unsetenv("G_MESSAGES_DEBUG"); 48 | var sp = launcher.spawnv(argv); 49 | 50 | if (sp == null) 51 | return (null); 52 | 53 | string? buf = null; 54 | if (!sp.communicate_utf8(null, cancellable, out buf, null)) 55 | return (null); 56 | 57 | var parts = buf.split(":"); 58 | 59 | if (parts.length < 7) 60 | { 61 | return (null); 62 | } 63 | 64 | return (parts[6].strip()); 65 | } 66 | 67 | public string[]? fp_get_env(Cancellable? cancellable = null) throws Error 68 | { 69 | if (!is_flatpak()) 70 | return (Environ.get()); 71 | 72 | string[] argv = { "flatpak-spawn", "--host", "env" }; 73 | 74 | var launcher = new GLib.SubprocessLauncher( 75 | SubprocessFlags.STDOUT_PIPE | SubprocessFlags.STDERR_SILENCE 76 | ); 77 | 78 | launcher.setenv("G_MESSAGES_DEBUG", "false", true); 79 | 80 | var sp = launcher.spawnv(argv); 81 | 82 | if (sp == null) 83 | return (null); 84 | 85 | string? buf = null; 86 | if (!sp.communicate_utf8(null, cancellable, out buf, null)) 87 | return (null); 88 | 89 | string[] arr = buf.strip().split("\n"); 90 | 91 | return (arr); 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/layouts/bottom_panel.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 82 | 83 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/actions/proton-build-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 21 | image/svg+xml 22 | 24 | 25 | 26 | 27 | 28 | 30 | 50 | 53 | 60 | 67 | 74 | 81 | 88 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/utils/utils.vala: -------------------------------------------------------------------------------- 1 | /* utils.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | namespace Proton 22 | { 23 | public bool is_flatpak() 24 | { 25 | return (FileUtils.test("/.flatpak-info", FileTest.EXISTS)); 26 | } 27 | 28 | public bool run_async(string? cwd, 29 | string command, 30 | out Pid _pid, 31 | out int standard_input = null, 32 | out int standard_output = null, 33 | out int standard_error = null) 34 | { 35 | try 36 | { 37 | string[] argv = {}; 38 | 39 | if (is_flatpak()) 40 | { 41 | argv += "flatpak-spawn"; 42 | argv += "--host"; 43 | } 44 | 45 | argv += "/usr/bin/bash"; 46 | 47 | var env = Environ.get(); 48 | 49 | foreach (var s in command.split(" ")) 50 | argv += s; 51 | 52 | return Process.spawn_async_with_pipes( 53 | cwd, 54 | argv, 55 | env, 56 | 0, 57 | null, 58 | out _pid, 59 | out standard_input, 60 | out standard_output, 61 | out standard_error 62 | ); 63 | } 64 | catch (SpawnError e) 65 | { 66 | warning(e.message); 67 | return (false); 68 | } 69 | } 70 | 71 | /** 72 | * Spawn a host command (both on flatpak and host) and get output. Your 73 | * command must be wrapped in single quotes and should be properly escaped. 74 | */ 75 | public bool spawn(string command, out string? stdout, out string? stderr, 76 | out int? status) throws SpawnError 77 | { 78 | string cmd = ""; 79 | 80 | if (is_flatpak()) 81 | { 82 | cmd += "flatpak-spawn --host "; 83 | } 84 | 85 | cmd += "/usr/bin/bash -c "; 86 | cmd += command; 87 | 88 | return (Process.spawn_command_line_sync(cmd, 89 | out stdout, 90 | out stderr, 91 | out status)); 92 | } 93 | 94 | /** 95 | * Search for a string `str` in a string array `arr`. Return a pointer to 96 | * the result or null. 97 | */ 98 | 99 | public unowned string? strvstr(string[] arr, string str) 100 | { 101 | size_t len; 102 | size_t i; 103 | 104 | len = arr.length; 105 | i = 0; 106 | while (i < len) 107 | { 108 | if (arr[i] == str) 109 | return (arr[i]); 110 | ++i; 111 | } 112 | return (null); 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /data/com.raggesilver.Proton.gschema.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | Use dark mode 7 | Use dark mode 8 | 9 | 10 | false 11 | Transparency 12 | Enable transparency on a few panels 13 | 14 | 15 | 800 16 | Width 17 | window width 18 | 19 | 20 | 400 21 | Height 22 | Window height 23 | 24 | 25 | -1 26 | X Pos 27 | X Pos 28 | 29 | 30 | -1 31 | Y Pos 32 | Y Pos 33 | 34 | 35 | [] 36 | Recent projects path 37 | Recent projects path 38 | 39 | 40 | 200 41 | Bottom panel height 42 | Bottom panel height 43 | 44 | 45 | false 46 | Bottom panel visible 47 | Bottom panel visible 48 | 49 | 50 | 200 51 | Left panel width 52 | Left panel width 53 | 54 | 55 | false 56 | Left panel visible 57 | Left panel visible 58 | 59 | 60 | 64 | 65 | 'Monospace 12' 66 | Font family 67 | Font family 68 | 69 | 70 | 'proton_dark' 71 | Style scheme id 72 | Style scheme id 73 | 74 | 75 | true 76 | Whether or not the editor should have a margin at the bottom 77 | Whether or not the editor should have a margin at the bottom 78 | 79 | 80 | true 81 | Whether or not the editor should wrap text 82 | Whether or not the editor should wrap text 83 | 84 | 85 | 89 | 90 | false 91 | Whether or not to save unsaved modified editors 92 | Editors that are modified (and not saved) and that got text replaced via Global Search are not saved by default. You can turn this feature on with this key. 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-vala.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 31 | 32 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-vala-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 31 | 32 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 69 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-meson.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 63 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-meson-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 41 | 43 | 44 | 46 | image/svg+xml 47 | 49 | 50 | 51 | 52 | 53 | 58 | 63 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /src/widgets/ide-grid/IdeGrid.vala: -------------------------------------------------------------------------------- 1 | /* IdeGrid.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.IdeGrid : Gtk.EventBox 22 | { 23 | MultiPaned paned; 24 | List stacks = new List(); 25 | IdeGridStack current_stack; 26 | weak Window window; 27 | 28 | public IdeGrid(Window _win) 29 | { 30 | window = _win; 31 | paned = new MultiPaned(Gtk.Orientation.HORIZONTAL); 32 | paned.show(); 33 | 34 | add(paned); 35 | 36 | current_stack = new_stack(); 37 | paned.add(current_stack); 38 | current_stack.show(); 39 | 40 | /* 41 | ** Create the actions handled by IdeGrid 42 | */ 43 | 44 | var a = new SimpleAction("open_file", VariantType.STRING); 45 | a.activate.connect((s) => { 46 | open_file(new File(s.get_string())); 47 | }); 48 | 49 | window.add_action(a); 50 | 51 | a = new SimpleAction("split_vertical", null); 52 | a.activate.connect(split_vertical); 53 | 54 | window.add_action(a); 55 | 56 | a = new SimpleAction("new_terminal", null); 57 | a.activate.connect(new_terminal); 58 | 59 | window.add_action(a); 60 | window.application.set_accels_for_action( 61 | "win.new_terminal", {"T"}); 62 | 63 | a = new SimpleAction("close_page", null); 64 | a.activate.connect(close_page); 65 | 66 | window.add_action(a); 67 | window.application.set_accels_for_action( 68 | "win.close_page", {"W"}); 69 | } 70 | 71 | IdeGridStack new_stack() 72 | { 73 | var s = new IdeGridStack(); 74 | 75 | s.close.connect(() => { 76 | return (stacks.length() > 1); 77 | }); 78 | 79 | s.focused.connect(() => { 80 | current_stack = s; 81 | }); 82 | 83 | s.destroy.connect(() => { 84 | stacks.remove(s); 85 | if (stacks.length() > 0) 86 | current_stack = stacks.last().data; 87 | }); 88 | 89 | stacks.append(s); 90 | return (s); 91 | } 92 | 93 | public void split_vertical() 94 | { 95 | var s = new_stack(); 96 | paned.add(s); 97 | current_stack = s; 98 | } 99 | 100 | public void open_file(File f) 101 | { 102 | Editor? ed = window.manager.get_editor(f); 103 | 104 | if (ed == null) 105 | { 106 | ed = window.manager.open(f); 107 | var p = new EditorGridPage(ed); 108 | 109 | current_stack.add_page(p); 110 | } 111 | else 112 | { 113 | // EditorGridPage detects sview.focus and asks it's current 114 | // IdeGridStack to be the visible child. Fixes #27 #31 115 | ed.sview.grab_focus(); 116 | } 117 | } 118 | 119 | public void new_terminal() 120 | { 121 | var t = new TerminalGridPage(window); 122 | current_stack.add_page(t); 123 | } 124 | 125 | public void close_page() 126 | { 127 | current_stack.close_page(); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /src/meson.build: -------------------------------------------------------------------------------- 1 | 2 | pluginsdir = join_paths(get_option('prefix'), get_option('libdir'), 'proton/plugins') 3 | 4 | conf_data = configuration_data() 5 | conf_data.set_quoted('PROJECT_NAME', meson.project_name()) 6 | conf_data.set_quoted('GETTEXT_PACKAGE', meson.project_name()) 7 | conf_data.set_quoted('VERSION', meson.project_version()) 8 | conf_data.set_quoted('PREFIX', get_option('prefix')) 9 | conf_data.set_quoted('PLUGINDIR', pluginsdir) 10 | conf_data.set_quoted('DATADIR', join_paths (get_option('prefix'), get_option('datadir'))) 11 | 12 | config_header = configure_file( 13 | input: 'config.vala.in', 14 | output: 'config.vala', 15 | configuration: conf_data 16 | ) 17 | 18 | proton_sources = [ 19 | 'main.vala', 20 | 'window.vala', 21 | 'application.vala', 22 | 'open_window.vala', 23 | 'about_window.vala', 24 | 'preferences_window.vala', 25 | 'utils/git/Cloner.vala', 26 | 'utils/File.vala', 27 | 'utils/utils.vala', 28 | 'utils/terminal/terminal.vala', 29 | 'utils/assert/assert.c', 30 | 'utils/assert/assert.h', 31 | 'utils/assert/assert.vala', 32 | 'services/Settings.vala', 33 | 'services/PluginManager.vala', 34 | 'services/Core.vala', 35 | 'services/EditorManager.vala', 36 | 'services/FileIconProvider.vala', 37 | ] 38 | 39 | proton_inc_dirs = [ 40 | 'utils/assert', 41 | ] 42 | 43 | subdir('widgets') 44 | 45 | proton_deps = [ 46 | dependency('gio-2.0', version: '>= 2.50'), 47 | dependency('gmodule-2.0', version: '>= 2.50'), 48 | dependency('gtksourceview-4', version: '>= 4.2.0'), 49 | dependency('gtk+-3.0', version: '>= 3.22'), 50 | dependency('json-glib-1.0', version: '>= 1.4.4'), 51 | dependency('libdazzle-1.0'), 52 | dependency('vte-2.91', version: '>= 0.57.0'), 53 | dependency('libgit2-glib-1.0', version: '>= 0.28.0.1'), 54 | dependency('marble'), 55 | meson.get_compiler('vala').find_library('linux'), 56 | meson.get_compiler('vala').find_library('posix'), 57 | ] 58 | 59 | gnome = import('gnome') 60 | 61 | proton_sources += gnome.compile_resources('proton-resources', 62 | 'proton.gresource.xml', c_name: 'proton') 63 | 64 | proton_core = library('proton_core', proton_sources, config_header, 65 | include_directories: proton_inc_dirs, 66 | dependencies: proton_deps, 67 | vala_gir: 'Proton-1.0.gir', 68 | install: true, 69 | install_dir: [ true, true, true, true ], 70 | version: '1.0', 71 | ) 72 | 73 | # This works, but not really, since Granite's nested namespaces are not 74 | # supported we get an error and are unable to continue. 75 | 76 | g_ir_compiler = find_program('g-ir-compiler') 77 | custom_target('proton_core typelib', 78 | command: [ 79 | g_ir_compiler, 80 | '--shared-library', proton_core.full_path(), 81 | # '--module', 'marble', 82 | '--output', '@OUTPUT@', 83 | '--debug', '--verbose', 84 | join_paths(meson.current_build_dir(), 'Proton-1.0.gir') 85 | ], 86 | output: 'Proton-1.0.typelib', 87 | depends: proton_core, 88 | install: true, 89 | install_dir: get_option('libdir') / 'girepository-1.0', 90 | ) 91 | 92 | pkg = import('pkgconfig') 93 | 94 | pkg.generate( 95 | version: '0.1', 96 | libraries: proton_core, 97 | description: 'Proton core', 98 | name: 'proton_core', 99 | filebase: 'proton_core' 100 | ) 101 | 102 | install_data('proton_core.deps', 103 | install_dir: join_paths(get_option('prefix'), get_option('datadir'), 'vala', 'vapi')) 104 | 105 | proton_core_dep = declare_dependency( 106 | link_with: proton_core, 107 | dependencies: proton_deps, 108 | include_directories: [include_directories('.')] 109 | ) 110 | 111 | subdir('plugins') 112 | 113 | executable('proton', 114 | link_with: proton_core, 115 | vala_args: '--target-glib=2.50', 116 | dependencies: proton_core_dep, 117 | install: true, 118 | ) 119 | 120 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-gitlab.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | gitlab-icon-rgb 27 | 28 | 29 | 30 | 50 | 52 | 54 | 55 | gitlab-icon-rgb 57 | 60 | 66 | 72 | 78 | 84 | 90 | 96 | 102 | 108 | 109 | 110 | -------------------------------------------------------------------------------- /src/layouts/command_palette.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | vertical 8 | 9 | 10 | True 11 | False 12 | 13 | 14 | stack 15 | True 16 | False 17 | center 18 | start 19 | 60 20 | False 21 | False 22 | 0 23 | True 24 | 25 | 26 | True 27 | False 28 | vertical 29 | 3 30 | 31 | 32 | True 33 | True 34 | center 35 | start 36 | 40 37 | 38 | 39 | False 40 | True 41 | 0 42 | 43 | 44 | 45 | 46 | True 47 | True 48 | never 49 | out 50 | 200 51 | 300 52 | True 53 | 54 | 55 | True 56 | False 57 | none 58 | 59 | 60 | True 61 | False 62 | 63 | 64 | 65 | 66 | 67 | 68 | False 69 | True 70 | 1 71 | 72 | 73 | 74 | 75 | main 76 | Command 77 | 78 | 79 | 80 | 81 | 82 | 83 | True 84 | True 85 | 0 86 | 87 | 88 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /src/widgets/global-search/GlobalSearch.vala: -------------------------------------------------------------------------------- 1 | /* GlobalSearch.vala 2 | * 3 | * Copyright 2020 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public class Proton.GlobalSearchSettings : Marble.Settings 22 | { 23 | private static Proton.GlobalSearchSettings? instance = null; 24 | 25 | public bool auto_save_modified { get; set; } 26 | 27 | private GlobalSearchSettings() 28 | { 29 | base("com.raggesilver.Proton.global-search"); 30 | } 31 | 32 | public static Proton.GlobalSearchSettings get_instance() 33 | { 34 | if (instance == null) 35 | instance = new Proton.GlobalSearchSettings(); 36 | return (instance); 37 | } 38 | } 39 | 40 | [GtkTemplate (ui = "/com/raggesilver/Proton/layouts/global_search.ui")] 41 | public class Proton.GlobalSearch : Gtk.Box 42 | { 43 | [GtkChild] private Gtk.Revealer include_files_revealer; 44 | [GtkChild] private Gtk.Revealer replace_revealer; 45 | [GtkChild] private Gtk.ToggleButton include_files_toggle_button; 46 | [GtkChild] private Gtk.Image toggle_image; 47 | [GtkChild] private Gtk.CheckButton auto_save_modified_check; 48 | [GtkChild] private Gtk.Entry search_entry; 49 | [GtkChild] private Gtk.Entry replace_entry; 50 | 51 | private weak Window window; 52 | private GlobalSearchSettings gs_settings; 53 | 54 | public GlobalSearch(Window window) 55 | { 56 | this.window = window; 57 | this.gs_settings = GlobalSearchSettings.get_instance(); 58 | 59 | this.auto_save_modified_check.active = this.gs_settings 60 | .auto_save_modified; 61 | this.gs_settings.schema.bind("auto-save-modified", 62 | this.auto_save_modified_check, "active", 63 | SettingsBindFlags.DEFAULT); 64 | 65 | // Bind accels 66 | this.bind_accels(); 67 | } 68 | 69 | private void bind_accels() 70 | { 71 | this.window.key_press_event.connect((e) => { 72 | if ((e.state & Gdk.ModifierType.CONTROL_MASK) == 0 || 73 | (e.state & Gdk.ModifierType.SHIFT_MASK) == 0) 74 | return (false); 75 | switch (Gdk.keyval_name(e.keyval)) 76 | { 77 | case "F": { this.on_ctrl_shift_f(); return (true); } 78 | case "H": { this.on_ctrl_shift_h(); return (true); } 79 | default: return (false); 80 | } 81 | }); 82 | } 83 | 84 | private void on_ctrl_shift_f() 85 | { 86 | this.window.side_panel_stack.set_visible_child_name("globalsearch"); 87 | this.search_entry.grab_focus(); 88 | } 89 | 90 | private void on_ctrl_shift_h() 91 | { 92 | this.window.side_panel_stack.set_visible_child_name("globalsearch"); 93 | 94 | if (!this.replace_revealer.reveal_child) 95 | this.on_toggle_replace(); 96 | 97 | this.replace_entry.grab_focus(); 98 | } 99 | 100 | [GtkCallback] 101 | private void on_include_files_toggled() 102 | { 103 | this.include_files_revealer.reveal_child = 104 | this.include_files_toggle_button.active; 105 | } 106 | 107 | [GtkCallback] 108 | private void on_toggle_replace() 109 | { 110 | this.replace_revealer.reveal_child = 111 | !this.replace_revealer.reveal_child; 112 | 113 | this.toggle_image.set_from_icon_name( 114 | (this.replace_revealer.reveal_child) ? "go-down-symbolic" : 115 | "go-next-symbolic", Gtk.IconSize.MENU 116 | ); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-js.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 60 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-js-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 60 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /src/services/PluginManager.vala: -------------------------------------------------------------------------------- 1 | /* PluginManager.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | public errordomain Proton.PluginError 22 | { 23 | NOT_SUPPORTED, 24 | UNEXPECTED_TYPE, 25 | NO_REGISTER_FUNCTION, 26 | FAILED 27 | } 28 | 29 | public interface Proton.PluginIface : Object 30 | { 31 | public abstract void do_register(PluginManager pm); 32 | public abstract void activate(); 33 | public abstract void deactivate(); 34 | } 35 | 36 | private class Proton.PluginInfo : Object 37 | { 38 | public Module module; 39 | public Type gtype; 40 | 41 | public PluginInfo(Type type, owned Module module) 42 | { 43 | this.module = (owned) module; 44 | this.gtype = type; 45 | } 46 | } 47 | 48 | private class Proton.Plug 49 | { 50 | public PluginIface iface; 51 | public PluginInfo info; 52 | } 53 | 54 | public class Proton.PluginManager : Object 55 | { 56 | [CCode (has_target = false)] 57 | private delegate Type RegisterPluginFunction(Module module); 58 | 59 | // Private 60 | Plug[] plugs = {}; 61 | 62 | // Public 63 | public Window window { get; private set; } 64 | 65 | public PluginManager(Window window) 66 | { 67 | this.window = window; 68 | } 69 | 70 | public async void load() 71 | { 72 | SourceFunc callback = load.callback; 73 | 74 | new Thread("plugin_manager_load", () => { 75 | try { do_load(); } 76 | catch(Error e) { error("Error: %s.", e.message); } 77 | Idle.add((owned)callback); 78 | return (true); 79 | }); 80 | 81 | yield; 82 | } 83 | 84 | private void do_load() throws Error 85 | { 86 | if (!Module.supported()) 87 | throw new PluginError.NOT_SUPPORTED("Plugins are not supported"); 88 | 89 | // Iterate through plugindir and load plugins 90 | var dir = Dir.open(Constants.PLUGINDIR); 91 | string? fname = null; 92 | 93 | while (null != (fname = dir.read_name())) 94 | { 95 | var f = new File( 96 | Constants.PLUGINDIR + Path.DIR_SEPARATOR_S + fname); 97 | 98 | var p = load_plugin(f); 99 | 100 | if (p != null) 101 | { 102 | p.iface.activate(); 103 | 104 | debug("Plugin '%s' loaded.", f.name); 105 | } 106 | } 107 | } 108 | 109 | private Plug? load_plugin(File f) 110 | { 111 | var pa = f.path + Path.DIR_SEPARATOR_S + "lib" + f.name; 112 | var module = Module.open(pa, ModuleFlags.LAZY); 113 | 114 | if (module == null) 115 | { 116 | warning("Failed to load plugin '%s'", f.path); 117 | warning("%s", Module.error()); 118 | return (null); 119 | } 120 | 121 | void *function; 122 | module.symbol("register_plugin", out function); 123 | if (function == null) 124 | { 125 | warning("Plugin '%s' has no register funcion", f.name); 126 | return (null); 127 | } 128 | 129 | var register_plugin = (RegisterPluginFunction)function; 130 | var type = register_plugin(module); 131 | 132 | if (type.is_a(typeof(PluginIface)) == false) 133 | { 134 | warning("Weird type for plugin '%s'", f.name); 135 | } 136 | 137 | PluginInfo info = new PluginInfo(type, (owned)module); 138 | 139 | var iface = (PluginIface)Object.new(type); 140 | iface.do_register(this); 141 | 142 | var p = new Plug(); 143 | p.iface = iface; 144 | p.info = info; 145 | 146 | Idle.add(() => { 147 | plugs += p; 148 | return (false); 149 | }); 150 | 151 | return (p); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-cpp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 61 | 66 | 70 | 74 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-cpp-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 40 | 42 | 43 | 45 | image/svg+xml 46 | 48 | 49 | 50 | 51 | 52 | 57 | 61 | 66 | 70 | 74 | 80 | 86 | 87 | 88 | 89 | 90 | 91 | -------------------------------------------------------------------------------- /src/layouts/status_box.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 43 | 44 | False 45 | box 46 | bottom 47 | 48 | 49 | True 50 | False 51 | 6 52 | 6 53 | 6 54 | 6 55 | 6 56 | 57 | 58 | True 59 | False 60 | vertical 61 | 62 | 63 | True 64 | False 65 | Project: 66 | 1 67 | 68 | 69 | False 70 | True 71 | 0 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | False 83 | True 84 | 0 85 | 86 | 87 | 88 | 89 | True 90 | False 91 | vertical 92 | 93 | 94 | True 95 | False 96 | <project_name> 97 | 0 98 | 99 | 100 | False 101 | True 102 | 0 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | True 114 | True 115 | 1 116 | 117 | 118 | 119 | 120 | 121 | 122 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-script2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 63 | 69 | 74 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-script2-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 55 | 60 | 64 | 70 | 75 | 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /data/icons/hicolor/scalable/mimetypes/text-x-gitlab-symbolic.svg: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 23 | image/svg+xml 24 | 26 | gitlab-icon-rgb 27 | 28 | 29 | 30 | 50 | 52 | 54 | 55 | gitlab-icon-rgb 57 | 60 | 66 | 72 | 78 | 79 | 84 | 91 | 98 | 99 | 104 | 108 | 114 | 115 | 119 | 125 | 126 | 130 | 136 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /src/layouts/editor_grid_page.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 92 | 93 | window-close-symbolic 94 | 95 | 96 | True 97 | False 98 | 99 | 100 | True 101 | True 102 | True 103 | 104 | 105 | True 106 | True 107 | 0 108 | 109 | 110 | 111 | 112 | True 113 | True 114 | True 115 | themedicon1 116 | 117 | 118 | False 119 | True 120 | 1 121 | 122 | 123 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /src/resources/style.css: -------------------------------------------------------------------------------- 1 | .base-color { 2 | background: @theme_base_color; 3 | } 4 | 5 | .bg-color { 6 | background: @theme_bg_color; 7 | } 8 | 9 | .wide-button { 10 | padding-left: 10px; 11 | padding-right: 10px; 12 | } 13 | 14 | .square { border-radius: 0; } 15 | 16 | button { 17 | -gtk-icon-shadow: none; 18 | outline: 0; 19 | } 20 | 21 | button.slim-button { 22 | padding: 0; 23 | } 24 | 25 | button.slim { 26 | padding: 0 2px; 27 | } 28 | 29 | #bottom_panel > box > stackswitcher > button { 30 | background: transparent; 31 | border: 0; 32 | border-bottom: 2px solid transparent; 33 | border-radius: 0; 34 | min-width: 0; 35 | padding-top: 2px; 36 | padding-bottom: 2px; 37 | margin: 4px 5px; 38 | box-shadow: none; 39 | font-size: 12px; 40 | color: alpha(@theme_fg_color, .7); 41 | } 42 | 43 | #bottom_panel > box > stackswitcher > button:checked { 44 | border-bottom-color: @theme_selected_bg_color; 45 | color: @theme_fg_color; 46 | } 47 | 48 | #bottom_panel > box > stackswitcher > button:not(:checked):hover { 49 | border-bottom-color: alpha(@theme_selected_bg_color, .5); 50 | } 51 | 52 | .open-window .titlebar { 53 | background: @theme_bg_color; 54 | border-bottom: 0; 55 | } 56 | 57 | .treeitem.selected > widget:first-child > box.horizontal { 58 | background-color: @theme_selected_bg_color; 59 | } 60 | 61 | .treeitem.selected:not(:backdrop) > widget:first-child > box.horizontal { 62 | color: @theme_selected_fg_color; 63 | } 64 | 65 | .treeitem.modified > widget:first-child > box.horizontal, 66 | .treeitem.modified > widget:first-child > box.horizontal label:backdrop { 67 | color: orange; 68 | } 69 | 70 | .treeitem.untracked > widget:first-child > box.horizontal, 71 | .treeitem.untracked > widget:first-child > box.horizontal label:backdrop { 72 | color: green; 73 | } 74 | 75 | .treeitem.error > widget:first-child > box.horizontal, 76 | .treeitem.error > widget:first-child > box.horizontal label:backdrop { 77 | color: red; 78 | } 79 | 80 | .completionpalette, 81 | .loadable > spinner { 82 | background-color: alpha(darker(@theme_bg_color), .6); 83 | } 84 | 85 | .statusbox { 86 | transition: .1s; 87 | min-height: 32px; 88 | padding-left: 1em; 89 | min-width: 20em; 90 | background: @theme_bg_color; 91 | border-radius: 5px; 92 | border: 1px solid @borders; 93 | } 94 | 95 | .statusbox > stack { 96 | margin-right: 1em; 97 | } 98 | 99 | .statusbox > label { 100 | margin-right: 1em; 101 | } 102 | 103 | .statusbox > * { 104 | margin: 0; 105 | border-top: 0; 106 | border-bottom: 0; 107 | } 108 | 109 | .statusbox > *:first-child { 110 | border-left: 0; 111 | } 112 | 113 | .statusbox > *:last-child { 114 | border-right: 0; 115 | } 116 | 117 | .statusbox.hover { 118 | background: shade(@theme_bg_color, 0.9); 119 | } 120 | 121 | .statusbox.click { 122 | background: shade(@theme_bg_color, 0.8); 123 | } 124 | 125 | .panel-header { 126 | border-bottom: 1px solid darker(@theme_base_color); 127 | background: @theme_base_color; 128 | } 129 | 130 | .panel-header > button { 131 | padding-top: 1px; 132 | padding-bottom: 1px; 133 | border-radius: 0; 134 | border: 0; 135 | color: alpha(@theme_fg_color, .75); 136 | text-shadow: none; 137 | box-shadow: none; 138 | } 139 | 140 | .panel-header > button:disabled { 141 | color: alpha(@theme_fg_color, .35); 142 | } 143 | 144 | .panel-header > * { 145 | background: transparent; 146 | } 147 | 148 | .panel-header > button:hover, 149 | .panel-header > button:checked, 150 | .panel-header > button:active { 151 | background: shade(@theme_base_color, .9); 152 | } 153 | 154 | button.close:not(.titlebutton) { 155 | padding: 0; 156 | color: inherit; 157 | border: none; 158 | } 159 | 160 | .titlebar.clean, 161 | .titlebar.clean>headerbar { 162 | border-bottom: 0; 163 | background: @theme_bg_color; 164 | } 165 | 166 | .dzldockbinedge.left, 167 | #search_box { border-right: 1px solid darker(@theme_base_color); } 168 | .dzldockbinedge.right, 169 | #search_box { border-left: 1px solid darker(@theme_base_color); } 170 | .dzldockbinedge.bottom { border-top: 1px solid darker(@theme_base_color); } 171 | .dzldockbinedge.top, 172 | #search_box { border-bottom: 1px solid darker(@theme_base_color); } 173 | 174 | /* side_panel_stack_switcher */ 175 | #spss button { opacity: 0.7; } 176 | #spss button:checked { opacity: 1; color: @theme_fg_color; background: @theme_base_color; } 177 | 178 | #search_box { 179 | background: @theme_base_color; 180 | border-bottom-left-radius: 8px; 181 | border-bottom-right-radius: 8px; 182 | padding: 6px; 183 | } 184 | 185 | #search_box * { font-size: 14px; } 186 | #search_box entry { border-radius: 0; font-size: 14px; min-height: 26px; } 187 | #search_box label.no-results { color: #C97362; } 188 | #search_box button.slim-button { padding: 0 2px; } 189 | 190 | #proton_window.transparent { background: transparent; } 191 | #proton_window.transparent .transparent { background: alpha(@theme_base_color, .96); } 192 | 193 | dzlmultipaned.handle { border: 1px solid darker(@theme_base_color); } 194 | 195 | entry.slim { min-height: 2em; font-size: 0.85em; } 196 | checkbutton.slim { font-size: .8em; } 197 | checkbutton.slim check { min-width: .8em; min-height: .8em; } 198 | 199 | #global_search { padding: 0 10px; } 200 | -------------------------------------------------------------------------------- /src/layouts/global_search_result.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 109 | 110 | -------------------------------------------------------------------------------- /src/utils/git/Cloner.vala: -------------------------------------------------------------------------------- 1 | /* Cloner.vala 2 | * 3 | * Copyright 2019 Paulo Queiroz 4 | * 5 | * This program is free software: you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation, either version 3 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | * GNU General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program. If not, see . 17 | * 18 | * SPDX-License-Identifier: GPL-3.0-or-later 19 | */ 20 | 21 | /* 22 | ** For whatever reason Ggit.RemoteCallbacks.new is protected, so a workarround 23 | ** is to create a derived class which has a public constructor 24 | */ 25 | 26 | public class Proton.RemoteCb : Ggit.RemoteCallbacks 27 | { 28 | public signal void message(string text); 29 | public signal void percentage(double percentage); 30 | public signal void complete(bool res); 31 | public signal void error(); 32 | 33 | construct 34 | { 35 | progress.connect((text) => { Idle.add(() => { 36 | debug("got text '%s'", text); 37 | message(text); 38 | return (false); 39 | }); }); 40 | 41 | transfer_progress.connect((stats) => { 42 | 43 | uint rec, total, index; 44 | 45 | rec = stats.get_received_objects(); 46 | total = stats.get_total_objects(); 47 | index = stats.get_indexed_objects(); 48 | 49 | var net_percent = (total > 0) ? rec * 100 / total / 2: 0; 50 | var ind_percent = (total > 0) ? index * 100 / total / 2 : 0; 51 | 52 | Idle.add(() => { 53 | percentage(net_percent + ind_percent); 54 | return (false); 55 | }); 56 | }); 57 | 58 | completion.connect((comp) => { 59 | debug("Hit complete"); 60 | if (comp == Ggit.RemoteCompletionType.ERROR) 61 | Idle.add(() => { 62 | error(); 63 | return (false); 64 | }); 65 | else 66 | Idle.add(() => { 67 | complete(true); 68 | return (false); 69 | }); 70 | }); 71 | } 72 | } 73 | 74 | public class Proton.Cloner : Object 75 | { 76 | public signal void complete(bool res); 77 | 78 | public RemoteCb callbacks { get; protected set; } 79 | public Ggit.FetchOptions fetch_ops { get; protected set; } 80 | public Ggit.CloneOptions clone_ops { get; protected set; } 81 | public Ggit.Repository? repo { get; protected set; } 82 | 83 | string url; 84 | File target; 85 | 86 | public Cloner(string url, File target) throws Error 87 | { 88 | assert_(Cloner.is_valid_target(target)); 89 | assert_(Cloner.is_valid_url(url)); 90 | 91 | Ggit.init(); 92 | 93 | this.url = url; 94 | this.target = target; 95 | 96 | clone_ops = new Ggit.CloneOptions(); 97 | fetch_ops = new Ggit.FetchOptions(); 98 | callbacks = new RemoteCb(); 99 | 100 | fetch_ops.set_remote_callbacks(callbacks); 101 | clone_ops.set_checkout_branch("master"); 102 | clone_ops.set_fetch_options(fetch_ops); 103 | 104 | repo = null; 105 | } 106 | 107 | public static bool is_valid_target(File target) 108 | { 109 | return (!target.exists || target.is_empty); 110 | } 111 | 112 | public static bool is_valid_url(string url) 113 | { 114 | try 115 | { 116 | var r = new Regex( 117 | "((git|ssh|http(s)?)|(git@[\\w\\.]+))(:(//)?)([\\w\\." 118 | + "@\\:/\\-~]+)(\\.git)(/)?", 119 | RegexCompileFlags.JAVASCRIPT_COMPAT 120 | ); 121 | 122 | return (r.match(url)); 123 | } 124 | catch(Error e) 125 | { 126 | warning(e.message); 127 | return (false); 128 | } 129 | } 130 | 131 | public void clone() 132 | { 133 | _do_clone.begin((obj, res) => { 134 | // Emit complete 135 | debug("Got to complete"); 136 | complete(_do_clone.end(res)); 137 | }); 138 | } 139 | 140 | async bool _do_clone() 141 | { 142 | SourceFunc callback = _do_clone.callback; 143 | 144 | bool res = false; 145 | 146 | new Thread("git_clone", () => { 147 | try 148 | { 149 | repo = Ggit.Repository.clone(url, target.file, clone_ops); 150 | debug("Got to line after"); 151 | assert_(repo != null); 152 | debug("Got after assert"); 153 | 154 | Idle.add((owned)callback); 155 | 156 | res = true; 157 | } 158 | catch(Error e) 159 | { 160 | warning("Cloning %s failed.", url); 161 | warning(e.message); 162 | Idle.add((owned)callback); 163 | } 164 | return (true); 165 | }); 166 | 167 | yield; 168 | 169 | return (res); 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /data/themes/proton-dark.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Paulo Queiroz 4 | <_description>Default theme for Proton. Based on Classic, Builder Dark and Solarized. 5 | 6 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | --------------------------------------------------------------------------------