Commit 3cfb70ac authored by Philip Chimento's avatar Philip Chimento Committed by Christian Hergert

sublime: Implement different actions for selection state

This adds a CSS class to IdeSourceViewMode, "has-selection", which is
added when text is selected in the underlying buffer.

We use this to implement different behaviour for some keybindings
depending on whether text is selected or not, in the Sublime Text
keybinding mode.
parent 3c33c5cc
...@@ -17,8 +17,7 @@ ...@@ -17,8 +17,7 @@
"clear-selection" () "clear-selection" ()
"remove-cursors" () "remove-cursors" ()
"redo" () }; "redo" () };
bind "<ctrl>c" { "copy-clipboard" () };
bind "<ctrl>x" { "cut-clipboard" () };
bind "<ctrl>v" { "paste-clipboard-extended" (1, 0, 0) }; bind "<ctrl>v" { "paste-clipboard-extended" (1, 0, 0) };
bind "<alt>slash" { "cycle-completion" (down) }; bind "<alt>slash" { "cycle-completion" (down) };
...@@ -26,18 +25,6 @@ ...@@ -26,18 +25,6 @@
bind "<alt>F9" { "sort" (1, 0) }; bind "<alt>F9" { "sort" (1, 0) };
bind "<shift>F9" { "sort" (0, 0) }; bind "<shift>F9" { "sort" (0, 0) };
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" () };
bind "<ctrl><alt>i" { "reindent" () }; bind "<ctrl><alt>i" { "reindent" () };
bind "<ctrl><shift>Up" { "move-lines" (0, -1) }; bind "<ctrl><shift>Up" { "move-lines" (0, -1) };
bind "<ctrl><shift>Down" { "move-lines" (0, 1) }; bind "<ctrl><shift>Down" { "move-lines" (0, 1) };
...@@ -85,9 +72,6 @@ ...@@ -85,9 +72,6 @@
bind "<alt><shift>Down" { "add-cursor" (column) }; bind "<alt><shift>Down" { "add-cursor" (column) };
bind "Escape" { "reset" () }; bind "Escape" { "reset" () };
bind "<ctrl>a" { "select-all" (1) }; bind "<ctrl>a" { "select-all" (1) };
/* Expand selection to line */
bind "<ctrl>l" { "movement" (first-char, 0, 0, 0)
"movement" (line-end, 1, 0, 0) };
/* Expand selection to brackets: this should be Ctrl+Shift+M, but that's /* Expand selection to brackets: this should be Ctrl+Shift+M, but that's
* hardcoded to uncomment the current line */ * hardcoded to uncomment the current line */
bind "<alt><shift>m" { "movement" (match-special, 1, 0, 0) }; bind "<alt><shift>m" { "movement" (match-special, 1, 0, 0) };
...@@ -102,7 +86,6 @@ ...@@ -102,7 +86,6 @@
bind "<shift>F3" { "action" ("editor-view", "move-previous-search-result", "") }; bind "<shift>F3" { "action" ("editor-view", "move-previous-search-result", "") };
bind "<ctrl>h" { "action" ("editor-view", "find-replace", "") }; bind "<ctrl>h" { "action" ("editor-view", "find-replace", "") };
bind "<ctrl><shift>e" { "action" ("editor-view", "find-replace", "") }; bind "<ctrl><shift>e" { "action" ("editor-view", "find-replace", "") };
bind "<ctrl>d" { "add-cursor" (match) };
bind "<ctrl>quoteleft" { "action" ("dockbin", "bottom-visible", "") }; bind "<ctrl>quoteleft" { "action" ("dockbin", "bottom-visible", "") };
bind "<shift>F11" { "action" ("win", "fullscreen", "") }; bind "<shift>F11" { "action" ("win", "fullscreen", "") };
...@@ -163,9 +146,6 @@ ...@@ -163,9 +146,6 @@
/* These don't originally have bindings in Sublime */ /* These don't originally have bindings in Sublime */
bind "<ctrl>k" { "action" ("layoutstack", "show-list", "") }; bind "<ctrl>k" { "action" ("layoutstack", "show-list", "") };
bind "<ctrl>u" { "change-case" (upper) };
bind "<alt>u" { "change-case" (lower) };
bind "<ctrl>asciitilde" { "change-case" (toggle) };
bind "<ctrl>0" { "reset-font-size" () }; bind "<ctrl>0" { "reset-font-size" () };
bind "<ctrl>KP_0" { "reset-font-size" () }; bind "<ctrl>KP_0" { "reset-font-size" () };
...@@ -220,18 +200,12 @@ ...@@ -220,18 +200,12 @@
* Alt+Q Wrap Paragraph At Ruler; needs an action for this * Alt+Q Wrap Paragraph At Ruler; needs an action for this
* *
* Known issues: * Known issues:
* Ctrl+C and Ctrl+X should copy and cut the current line if there is no * Ctrl+D and Ctrl+L: The transition to the 'has-selection' state doesn't
* selection. * happen when the selection is initiated from a keybinding, so pressing
* Ctrl+U, Alt+U, and Ctrl+Shift+~ should operate on the current word if * Ctrl+D twice doesn't select a word and its next occurrence, and
* there is no selection. * likewise pressing Ctrl+L twice doesn't select two lines.
* Ctrl+L should add the next line to the selection if there is already a * Ctrl+[, Ctrl+] Indent and Unindent; These should preserve the place of
* selection. * the insert mark relative to the text, instead of the line offset.
* Ctrl+D should select the current word if there is no selection.
* Ctrl+[, Ctrl+] Indent and Unindent; these only work on single lines.
* Tab and Shift+Tab work on an entire selection, but these bindings seem
* to be hardcoded in GtkSourceView. They should also preserve the place
* of the insert mark relative to the text (instead of relative to the
* line offset.)
* Some shortcuts (Ctrl+Enter, Ctrl+M, Ctrl+Shift+M, Ctrl+Shift+U, F9) * Some shortcuts (Ctrl+Enter, Ctrl+M, Ctrl+Shift+M, Ctrl+Shift+U, F9)
* apparently can't be overridden. * apparently can't be overridden.
* Ctrl+Alt+Q doesn't toggle macro recording. Instead, use Ctrl+Super+Q to * Ctrl+Alt+Q doesn't toggle macro recording. Instead, use Ctrl+Super+Q to
...@@ -243,6 +217,77 @@ ...@@ -243,6 +217,77 @@
*/ */
} }
/* 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 @binding-set sublime-workbench-bindings
{ {
bind "<ctrl>less" { "action" ("app", "preferences", "") }; bind "<ctrl>less" { "action" ("app", "preferences", "") };
...@@ -257,6 +302,13 @@ window.workbench { ...@@ -257,6 +302,13 @@ window.workbench {
.sourceview, .sourceview,
idesourceviewmode.default { idesourceviewmode.default {
-gtk-key-bindings: sublime-ide-source-view, -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; sublime-workbench-bindings;
} }
\ No newline at end of file
...@@ -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