Commit f5b52021 authored by Christian Hergert's avatar Christian Hergert

Merge branch 'ptomato/gnome-builder-wip/sublime-keybindings'

parents eb551e22 3cfb70ac
Pipeline #16272 passed with stage
in 17 minutes and 18 seconds
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
<choice value="default"/> <choice value="default"/>
<choice value="emacs"/> <choice value="emacs"/>
<choice value="vim"/> <choice value="vim"/>
<choice value="sublime"/>
</choices> </choices>
<default>'default'</default> <default>'default'</default>
</key> </key>
......
@import url("resource:///org/gnome/builder/keybindings/shared.css");
@binding-set sublime-ide-source-view
{
bind "<ctrl>n" { "action" ("editor", "new-file", "") };
bind "<ctrl>o" { "action" ("win", "open-with-dialog", "") };
bind "<ctrl>s" { "action" ("editor-view", "save", "") };
bind "<ctrl><shift>s" { "action" ("editor-view", "save-as", "") };
bind "<ctrl>w" { "action" ("layoutstack", "close-view", "") };
bind "<ctrl>q" { "action" ("app", "quit", "") };
bind "<ctrl>z" { "clear-count" ()
"clear-selection" ()
"remove-cursors" ()
"undo" () };
bind "<ctrl><shift>z" { "clear-count" ()
"clear-selection" ()
"remove-cursors" ()
"redo" () };
bind "<ctrl>v" { "paste-clipboard-extended" (1, 0, 0) };
bind "<alt>slash" { "cycle-completion" (down) };
/* This should be F9, but that is hardcoded to hide the sidebar instead */
bind "<alt>F9" { "sort" (1, 0) };
bind "<shift>F9" { "sort" (0, 0) };
bind "<ctrl><alt>i" { "reindent" () };
bind "<ctrl><shift>Up" { "move-lines" (0, -1) };
bind "<ctrl><shift>Down" { "move-lines" (0, 1) };
bind "<ctrl><shift>d" { "duplicate-entire-line" () };
bind "<ctrl><shift>k" { "delete-from-cursor" (paragraphs, 1) };
bind "<ctrl>j" { "join-lines" () };
/* Insert line above */
bind "<ctrl><shift>Return" { "begin-user-action" ()
"movement" (first-char, 0, 0, 0)
"insert-at-cursor" ("\n")
"move-cursor" (display-lines, -1, 0)
"reindent" ()
"end-user-action" () };
bind "<ctrl><shift>KP_Enter" { "begin-user-action" ()
"movement" (first-char, 0, 0, 0)
"insert-at-cursor" ("\n")
"move-cursor" (display-lines, -1, 0)
"reindent" ()
"end-user-action" () };
/* Insert line below. This should be Ctrl+Enter but that is hardcoded to
* open the command bar. So we add Alt+Enter instead, but also accept
* Ctrl+Enter on the keypad */
bind "<alt>Return" { "begin-user-action" ()
"movement" (line-end, 0, 1, 0)
"insert-at-cursor" ("\n")
"reindent" ()
"end-user-action" () };
bind "<alt>KP_Enter" { "begin-user-action" ()
"movement" (line-end, 0, 1, 0)
"insert-at-cursor" ("\n")
"reindent" ()
"end-user-action" () };
bind "<ctrl>KP_Enter" { "begin-user-action" ()
"movement" (line-end, 0, 1, 0)
"insert-at-cursor" ("\n")
"reindent" ()
"end-user-action" () };
bind "<ctrl>Delete" { "delete-from-cursor" (words, 1) };
bind "<ctrl>KP_Delete" { "delete-from-cursor" (words, 1) };
bind "<ctrl>BackSpace" { "delete-from-cursor" (words, -1) };
bind "<ctrl>t" { "move-words" (1) };
bind "<alt><shift>Down" { "add-cursor" (column) };
bind "Escape" { "reset" () };
bind "<ctrl>a" { "select-all" (1) };
/* Expand selection to brackets: this should be Ctrl+Shift+M, but that's
* hardcoded to uncomment the current line */
bind "<alt><shift>m" { "movement" (match-special, 1, 0, 0) };
bind "<ctrl><shift>a" { "select-tag" (1) };
bind "<ctrl>f" { "action" ("editor-view", "find", "") };
/* Make "Incremental search" and "Use selection for search" do the same thing
* as Ctrl+F, in Builder they are all the same anyway */
bind "<ctrl>i" { "action" ("editor-view", "find", "") };
bind "<ctrl>e" { "action" ("editor-view", "find", "") };
bind "F3" { "action" ("editor-view", "move-next-search-result", "") };
bind "<shift>F3" { "action" ("editor-view", "move-previous-search-result", "") };
bind "<ctrl>h" { "action" ("editor-view", "find-replace", "") };
bind "<ctrl><shift>e" { "action" ("editor-view", "find-replace", "") };
bind "<ctrl>quoteleft" { "action" ("dockbin", "bottom-visible", "") };
bind "<shift>F11" { "action" ("win", "fullscreen", "") };
bind "F6" { "action" ("spellcheck", "spellcheck", "") };
bind "<alt>exclam" { "action" ("layoutstack", "split-view", "''") };
bind "<alt><shift>KP_1" { "action" ("layoutstack", "split-view", "''") };
bind "<ctrl>r" { "action" ("symbol-tree", "search", "") };
bind "F12" { "goto-definition" () };
bind "<ctrl>g" { "action" ("editor-view", "goto-line", "") };
bind "<alt>minus" { "action" ("history", "move-previous-edit", "") };
bind "<alt>underscore" { "action" ("history", "move-next-edit", "") };
/* Goto matching bracket; should be Ctrl+M but that is hardcoded to comment
* out the current line */
bind "<alt>m" { "movement" (match-special, 0, 1, 1) };
bind "<super><shift>h" { "clear-selection" ()
"movement" (previous-word-end, 0, 1, 1)
"movement" (next-word-start, 0, 1, 0)
"movement" (next-word-end, 1, 0, 1)
"request-documentation" ()
"clear-count" ()
"clear-selection" () };
bind "<ctrl><super>e" { "move-error" (down) };
bind "<ctrl><super><shift>e" { "move-error" (up) };
bind "<ctrl>Page_Up" { "action" ("layoutstack", "previous-view", "") };
bind "<ctrl>KP_Page_Up" { "action" ("layoutstack", "previous-view", "") };
bind "<ctrl>Page_Down" { "action" ("layoutstack", "next-view", "") };
bind "<ctrl>KP_Page_Down" { "action" ("layoutstack", "next-view", "") };
bind "<ctrl>Tab" { "action" ("layoutstack", "next-view", "") };
bind "<ctrl><shift>Tab" { "action" ("layoutstack", "previous-view", "") };
bind "<alt>o" { "action" ("win", "find-other-file", "") };
bind "<ctrl>Up" { "movement" (screen-up, 0, 0, 0) };
bind "<ctrl>KP_Up" { "movement" (screen-up, 0, 0, 0) };
bind "<ctrl>Down" { "movement" (screen-down, 0, 0, 0) };
bind "<ctrl>KP_Down" { "movement" (screen-down, 0, 0, 0) };
bind "<ctrl><shift>p" { "action" ("win", "show-command-bar", "") };
bind "<ctrl>b" { "action" ("build-manager", "build", "") };
/* Ctrl+Shift+B is Build with Build System in Sublime Text; Builder doesn't
* have this concept. Instead you configure the build system in the Build
* Preferences perspective, so let's have that keybinding take us there. */
bind "<ctrl><shift>b" { "action" ("buildui", "configure", "''") };
/* Sublime has a "Toggle macro recording" key. Builder has begin/end
* recording, so we add an extra shortcut for end */
bind "<ctrl><alt>q" { "begin-macro" () };
bind "<ctrl><super>q" { "end-macro" () };
bind "<ctrl><alt><shift>q" { "replay-macro" (1) };
bind "<ctrl>minus" { "decrease-font-size" () };
bind "<ctrl>KP_Subtract" { "decrease-font-size" () };
bind "<ctrl>plus" { "increase-font-size" () };
bind "<ctrl>equal" { "increase-font-size" () };
bind "<ctrl>KP_Add" { "increase-font-size" () };
/* These don't originally have bindings in Sublime */
bind "<ctrl>k" { "action" ("layoutstack", "show-list", "") };
bind "<ctrl>0" { "reset-font-size" () };
bind "<ctrl>KP_0" { "reset-font-size" () };
/* Not in Sublime Text by default, but nice macros */
bind "<ctrl>semicolon" { "save-insert-mark" ()
"movement" (line-end, 0, 1, 0)
"insert-at-cursor" (";")
"restore-insert-mark" () };
bind "<ctrl>comma" { "save-insert-mark" ()
"movement" (line-end, 0, 1, 0)
"insert-at-cursor" (",")
"restore-insert-mark" () };
/* Add back emoji with a different shortcut */
bind "<ctrl>colon" { "insert-emoji" () };
/* Not bound:
* Ctrl+Shift+Space Expand selection to scope; Highlighting scope is a
* concept that doesn't exist in Builder
* Ctrl+Alt+Shift+P Show scope name; ditto
* F4, Shift+F4 Previous/next search result in results panel; Builder
* doesn't have a results panel
* Ctrl+1, Ctrl+Shift+1, etc; Builder doesn't have multiple layout stacks
* Alt+Shift+2, etc; Builder can open vertical splits and close them, which
* is already plenty of flexibility for splitting windows
*
* Not yet bound, but probably could be with some extra code:
* Ctrl+Shift+T Reopen last closed file
* Ctrl+Shift+V Paste and indent; needs extra parameter to
* paste-clipboard-extended, to select pasted text so we can reindent it
* Ctrl+Shift+J Expand selection to indentation; selects every contiguous
* line at the current indendation level or deeper. Needs movement type
* Alt+1, Alt+2, etc. Go to position in stack; needs a goto-view action in
* ide-layout-stack-actions.c
* Alt+. Close Tag; nice to have for editing HTML
* Alt+Shift+W Wrap Selection with Tag; inserts <p> and </p> around the
* selection, and selects both "p"'s
* Ctrl+Alt+Shift+K Goto Previous Git Difference
* Ctrl+Shift+F Find in Files, Ctrl+Shift+R Goto Symbol in Project; Builder
* doesn't have global search yet
* Ctrl+F2 Toggle Bookmark, etc; GtkSourceView doesn't have actions for this
* Ctrl+/, Ctrl+Shift+/ Toggle Line/Block Comment; comment/uncomment seems
* to be hardcoded to Ctrl+M and Ctrl+Shift+M
* Ctrl+Shift+L Split Selection into Lines
* Alt+Shift+Up/Down Add Cursor on Previous/Next Line; currently
* add_cursor(column) only works if there's a selection.
* Ctrl+F3 Quick Find; expands selection to current word if no selection,
* and jumps immediately to next match
* Alt+F3 Quick Find All; expands selection to current word if no selection,
* and selects all matches
* F4 Build Results; needs an action to go to the Build Issues pane of the
* sidebar
* Alt+Q Wrap Paragraph At Ruler; needs an action for this
*
* Known issues:
* Ctrl+D and Ctrl+L: The transition to the 'has-selection' state doesn't
* happen when the selection is initiated from a keybinding, so pressing
* Ctrl+D twice doesn't select a word and its next occurrence, and
* likewise pressing Ctrl+L twice doesn't select two lines.
* Ctrl+[, Ctrl+] Indent and Unindent; These should preserve the place of
* the insert mark relative to the text, instead of the line offset.
* Some shortcuts (Ctrl+Enter, Ctrl+M, Ctrl+Shift+M, Ctrl+Shift+U, F9)
* apparently can't be overridden.
* Ctrl+Alt+Q doesn't toggle macro recording. Instead, use Ctrl+Super+Q to
* stop recording.
* Ctrl+Alt+P, Switch Project, doesn't work when the editor view is focused.
* Previous Error and Next Error were originally bound to Ctrl+K, P and
* Ctrl+K, N on SublimeLinter for Linux. We use the shortcuts from macOS
* in order to avoid a separate Ctrl+K state.
*/
}
/* Keys that work differently depending on whether there is text selected */
@binding-set sublime-ide-source-view-no-selection
{
/* Ctrl+C without anything selected copies the entire line incl. newline */
bind "<ctrl>c" { "save-insert-mark" ()
"movement" (first-char, 0, 0, 0)
"movement" (line-end, 1, 0, 0)
"copy-clipboard" ()
"clear-selection" ()
"restore-insert-mark" () };
/* Ditto Ctrl+X for cut */
bind "<ctrl>x" { "movement" (first-char, 0, 0, 0)
"movement" (line-end, 1, 0, 0)
"copy-clipboard" ()
"delete-selection" () };
/* Expand selection to word - is Quick Add Next when there's a selection */
bind "<ctrl>d" { "movement" (previous-word-end, 0, 1, 1)
"movement" (next-word-start, 0, 1, 0)
"movement" (next-word-end, 1, 0, 1) };
bind "<ctrl>bracketleft" { "save-insert-mark" ()
"movement" (first-char, 0, 1, 0)
"movement" (line-end, 1, 1, 0)
"indent-selection" (-1)
"clear-selection" ()
"restore-insert-mark" () };
bind "<ctrl>bracketright" { "save-insert-mark" ()
"movement" (first-char, 0, 1, 0)
"movement" (line-end, 1, 1, 0)
"indent-selection" (1)
"clear-selection" ()
"restore-insert-mark" () };
/* Expand selection to line */
bind "<ctrl>l" { "movement" (first-char, 0, 0, 0)
"movement" (line-end, 1, 0, 0) };
/* These don't originally have bindings in Sublime */
bind "<ctrl>u" { "save-insert-mark" ()
"movement" (previous-word-end, 0, 1, 1)
"movement" (next-word-start, 0, 1, 0)
"movement" (next-word-end, 1, 0, 1)
"change-case" (upper)
"restore-insert-mark" () };
bind "<alt>u" { "save-insert-mark" ()
"movement" (previous-word-end, 0, 1, 1)
"movement" (next-word-start, 0, 1, 0)
"movement" (next-word-end, 1, 0, 1)
"change-case" (lower)
"restore-insert-mark" () };
bind "<ctrl>asciitilde" { "save-insert-mark" ()
"movement" (previous-word-end, 0, 1, 1)
"movement" (next-word-start, 0, 1, 0)
"movement" (next-word-end, 1, 0, 1)
"change-case" (toggle)
"restore-insert-mark" () };
}
@binding-set sublime-ide-source-view-has-selection
{
bind "<ctrl>c" { "copy-clipboard" () };
bind "<ctrl>x" { "cut-clipboard" () };
bind "<ctrl>d" { "add-cursor" (match) };
bind "<ctrl>bracketleft" { "indent-selection" (-1) };
bind "<ctrl>bracketright" { "indent-selection" (1) };
bind "<ctrl>l" { "movement" (line-end, 1, 0, 0) };
bind "<ctrl>u" { "change-case" (upper) };
bind "<alt>u" { "change-case" (lower) };
bind "<ctrl>asciitilde" { "change-case" (toggle) };
}
@binding-set sublime-workbench-bindings
{
bind "<ctrl>less" { "action" ("app", "preferences", "") };
bind "<ctrl>p" { "action" ("win", "global-search", "") };
/* No quick project switcher in Builder, but we bind this to Open Project */
bind "<ctrl><alt>p" { "action" ("app", "open-project", "") };
}
window.workbench {
-gtk-key-bindings: sublime-workbench-bindings;
}
.sourceview,
idesourceviewmode.default {
-gtk-key-bindings: sublime-ide-source-view-no-selection,
sublime-ide-source-view,
sublime-workbench-bindings;
}
idesourceviewmode.default.has-selection {
-gtk-key-bindings: sublime-ide-source-view-has-selection,
sublime-ide-source-view,
sublime-workbench-bindings;
}
\ No newline at end of file
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
<file alias="default.css">keybindings/default.css</file> <file alias="default.css">keybindings/default.css</file>
<file alias="emacs.css">keybindings/emacs.css</file> <file alias="emacs.css">keybindings/emacs.css</file>
<file alias="shared.css">keybindings/shared.css</file> <file alias="shared.css">keybindings/shared.css</file>
<file alias="sublime.css">keybindings/sublime.css</file>
<file alias="vim.css">keybindings/vim.css</file> <file alias="vim.css">keybindings/vim.css</file>
</gresource> </gresource>
......
...@@ -142,6 +142,7 @@ ide_preferences_builtin_register_keyboard (DzlPreferences *preferences) ...@@ -142,6 +142,7 @@ ide_preferences_builtin_register_keyboard (DzlPreferences *preferences)
dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"default\"", _("Builder"), _("Default keybinding mode which mimics gedit"), NULL, 0); dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"default\"", _("Builder"), _("Default keybinding mode which mimics gedit"), NULL, 0);
dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"emacs\"", _("Emacs"), _("Emulates the Emacs text editor"), NULL, 0); dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"emacs\"", _("Emacs"), _("Emulates the Emacs text editor"), NULL, 0);
dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"vim\"", _("Vim"), _("Emulates the Vim text editor"), NULL, 0); dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"vim\"", _("Vim"), _("Emulates the Vim text editor"), NULL, 0);
dzl_preferences_add_radio (preferences, "keyboard", "mode", "org.gnome.builder.editor", "keybindings", NULL, "\"sublime\"", _("Sublime Text"), _("Emulates the Sublime Text editor"), NULL, 0);
dzl_preferences_add_list_group (preferences, "keyboard", "movements", _("Movement"), GTK_SELECTION_NONE, 100); dzl_preferences_add_list_group (preferences, "keyboard", "movements", _("Movement"), GTK_SELECTION_NONE, 100);
dzl_preferences_add_switch (preferences, "keyboard", "movements", "org.gnome.builder.editor", "smart-home-end", NULL, NULL, _("Smart Home and End"), _("Home moves to first non-whitespace character"), NULL, 0); dzl_preferences_add_switch (preferences, "keyboard", "movements", "org.gnome.builder.editor", "smart-home-end", NULL, NULL, _("Smart Home and End"), _("Home moves to first non-whitespace character"), NULL, 0);
......
...@@ -598,3 +598,19 @@ ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self, ...@@ -598,3 +598,19 @@ ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self,
else else
gtk_style_context_remove_class (style_context, "has-indenter"); gtk_style_context_remove_class (style_context, "has-indenter");
} }
void
ide_source_view_mode_set_has_selection (IdeSourceViewMode *self,
gboolean has_selection)
{
GtkStyleContext *style_context;
g_assert (IDE_IS_SOURCE_VIEW_MODE (self));
style_context = gtk_widget_get_style_context (GTK_WIDGET (self));
if (has_selection)
gtk_style_context_add_class (style_context, "has-selection");
else
gtk_style_context_remove_class (style_context, "has-selection");
}
...@@ -39,6 +39,8 @@ gboolean ide_source_view_mode_get_keep_mark_on_char (IdeSou ...@@ -39,6 +39,8 @@ gboolean ide_source_view_mode_get_keep_mark_on_char (IdeSou
IdeSourceViewModeType ide_source_view_mode_get_mode_type (IdeSourceViewMode *self); IdeSourceViewModeType ide_source_view_mode_get_mode_type (IdeSourceViewMode *self);
void ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self, void ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self,
gboolean has_indenter); gboolean has_indenter);
void ide_source_view_mode_set_has_selection (IdeSourceViewMode *self,
gboolean has_selection);
IdeSourceViewMode *_ide_source_view_mode_new (GtkWidget *view, IdeSourceViewMode *_ide_source_view_mode_new (GtkWidget *view,
const char *mode, const char *mode,
IdeSourceViewModeType type) G_GNUC_INTERNAL; IdeSourceViewModeType type) G_GNUC_INTERNAL;
......
...@@ -1158,12 +1158,17 @@ ide_source_view__buffer_notify_has_selection_cb (IdeSourceView *self, ...@@ -1158,12 +1158,17 @@ ide_source_view__buffer_notify_has_selection_cb (IdeSourceView *self,
GParamSpec *pspec, GParamSpec *pspec,
IdeBuffer *buffer) IdeBuffer *buffer)
{ {
IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
gboolean has_selection;
IdeWorkbench *workbench = ide_widget_get_workbench (GTK_WIDGET (self)); IdeWorkbench *workbench = ide_widget_get_workbench (GTK_WIDGET (self));
has_selection = gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer));
ide_source_view_mode_set_has_selection (priv->mode, has_selection);
if (workbench == NULL) if (workbench == NULL)
return; return;
if (gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer))) if (has_selection)
ide_workbench_set_selection_owner (workbench, G_OBJECT (self)); ide_workbench_set_selection_owner (workbench, G_OBJECT (self));
else if (ide_workbench_get_selection_owner (workbench) == G_OBJECT (self)) else if (ide_workbench_get_selection_owner (workbench) == G_OBJECT (self))
ide_workbench_set_selection_owner (workbench, NULL); ide_workbench_set_selection_owner (workbench, NULL);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment