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 @@
"clear-selection" ()
"remove-cursors" ()
"redo" () };
bind "<ctrl>c" { "copy-clipboard" () };
bind "<ctrl>x" { "cut-clipboard" () };
bind "<ctrl>v" { "paste-clipboard-extended" (1, 0, 0) };
bind "<alt>slash" { "cycle-completion" (down) };
......@@ -26,18 +25,6 @@
bind "<alt>F9" { "sort" (1, 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><shift>Up" { "move-lines" (0, -1) };
bind "<ctrl><shift>Down" { "move-lines" (0, 1) };
......@@ -85,9 +72,6 @@
bind "<alt><shift>Down" { "add-cursor" (column) };
bind "Escape" { "reset" () };
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
* hardcoded to uncomment the current line */
bind "<alt><shift>m" { "movement" (match-special, 1, 0, 0) };
......@@ -102,7 +86,6 @@
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>d" { "add-cursor" (match) };
bind "<ctrl>quoteleft" { "action" ("dockbin", "bottom-visible", "") };
bind "<shift>F11" { "action" ("win", "fullscreen", "") };
......@@ -163,9 +146,6 @@
/* These don't originally have bindings in Sublime */
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>KP_0" { "reset-font-size" () };
......@@ -220,18 +200,12 @@
* Alt+Q Wrap Paragraph At Ruler; needs an action for this
*
* Known issues:
* Ctrl+C and Ctrl+X should copy and cut the current line if there is no
* selection.
* Ctrl+U, Alt+U, and Ctrl+Shift+~ should operate on the current word if
* there is no selection.
* Ctrl+L should add the next line to the selection if there is already a
* selection.
* 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.)
* 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
......@@ -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
{
bind "<ctrl>less" { "action" ("app", "preferences", "") };
......@@ -257,6 +302,13 @@ window.workbench {
.sourceview,
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;
}
\ No newline at end of file
......@@ -598,3 +598,19 @@ ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self,
else
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
IdeSourceViewModeType ide_source_view_mode_get_mode_type (IdeSourceViewMode *self);
void ide_source_view_mode_set_has_indenter (IdeSourceViewMode *self,
gboolean has_indenter);
void ide_source_view_mode_set_has_selection (IdeSourceViewMode *self,
gboolean has_selection);
IdeSourceViewMode *_ide_source_view_mode_new (GtkWidget *view,
const char *mode,
IdeSourceViewModeType type) G_GNUC_INTERNAL;
......
......@@ -1158,12 +1158,17 @@ ide_source_view__buffer_notify_has_selection_cb (IdeSourceView *self,
GParamSpec *pspec,
IdeBuffer *buffer)
{
IdeSourceViewPrivate *priv = ide_source_view_get_instance_private (self);
gboolean has_selection;
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)
return;
if (gtk_text_buffer_get_has_selection (GTK_TEXT_BUFFER (buffer)))
if (has_selection)
ide_workbench_set_selection_owner (workbench, G_OBJECT (self));
else if (ide_workbench_get_selection_owner (workbench) == G_OBJECT (self))
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