diff --git a/Cargo.lock b/Cargo.lock index 38a6743d5ff5d3d1bc387be9a20157e784fd2b47..ecfea4817a1936b6fa12b59956b971c2e255ca88 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2588,6 +2588,7 @@ dependencies = [ "tree-sitter", "tree-sitter-json 0.19.0", "tree-sitter-rust", + "tree-sitter-typescript", "unindent", "util", ] @@ -5857,7 +5858,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" [[package]] name = "zed" -version = "0.29.0" +version = "0.30.0" dependencies = [ "anyhow", "assets", diff --git a/assets/icons/broadcast-24.svg b/assets/icons/broadcast-24.svg deleted file mode 100644 index 391528cdc7fa6ee815e9e94e65c24617a932c2af..0000000000000000000000000000000000000000 --- a/assets/icons/broadcast-24.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/assets/icons/share.svg b/assets/icons/share.svg new file mode 100644 index 0000000000000000000000000000000000000000..ee8ddfffc9df64e726fd39833483fad08a9abdf4 --- /dev/null +++ b/assets/icons/share.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/keymaps/default.json b/assets/keymaps/default.json index 28e5ed574c71270feb56787d90eb6a198fed9816..af47a165f96e0d1636542e657ee8ae7f931fb513 100644 --- a/assets/keymaps/default.json +++ b/assets/keymaps/default.json @@ -210,9 +210,11 @@ "cmd-shift-F": "project_search::Deploy", "cmd-k cmd-t": "theme_selector::Toggle", "cmd-k t": "theme_selector::Reload", + "cmd-k cmd-s": "zed::OpenKeymap", "cmd-t": "project_symbols::Toggle", "cmd-p": "file_finder::Toggle", - "cmd-shift-P": "command_palette::Toggle" + "cmd-shift-P": "command_palette::Toggle", + "cmd-shift-M": "diagnostics::Deploy" } }, // Bindings from Sublime Text @@ -244,6 +246,7 @@ "cmd-k cmd-right": "workspace::ActivateNextPane" } }, + // Bindings from Atom { "context": "Pane", "bindings": { @@ -289,18 +292,13 @@ { "bindings": { "ctrl-alt-cmd-f": "workspace::FollowNextCollaborator", - "cmd-alt-i": "zed::DebugElements", - "alt-cmd-,": "zed::OpenKeymap" + "cmd-alt-i": "zed::DebugElements" } }, { "context": "Editor", "bindings": { - "ctrl-w": "editor::SelectLargerSyntaxNode", - "ctrl-shift-W": "editor::SelectSmallerSyntaxNode", - "alt-cmd-f": "editor::FoldSelectedRanges", - "alt-enter": "editor::OpenExcerpts", - "cmd-f10": "editor::RestartLanguageServer" + "alt-enter": "editor::OpenExcerpts" } }, { @@ -312,8 +310,6 @@ { "context": "Workspace", "bindings": { - "alt-shift-D": "diagnostics::Deploy", - "ctrl-alt-cmd-j": "journal::NewJournalEntry", "cmd-1": [ "workspace::ToggleSidebarItemFocus", { diff --git a/assets/keymaps/vim.json b/assets/keymaps/vim.json index c0745afd9967fc17ab5ae69eb3643b370bbc4220..0cf51568fe3b7e2e0bbc842a96bf274d15a8a4c0 100644 --- a/assets/keymaps/vim.json +++ b/assets/keymaps/vim.json @@ -75,37 +75,13 @@ { "context": "Editor && vim_operator == c", "bindings": { - "w": [ - "vim::NextWordEnd", - { - "ignorePunctuation": false - } - ], + "w": "vim::ChangeWord", "shift-W": [ - "vim::NextWordEnd", + "vim::ChangeWord", { "ignorePunctuation": true } ] } - }, - { - "context": "Editor && vim_operator == d", - "bindings": { - "w": [ - "vim::NextWordStart", - { - "ignorePunctuation": false, - "stopAtNewline": true - } - ], - "shift-W": [ - "vim::NextWordStart", - { - "ignorePunctuation": true, - "stopAtNewline": true - } - ] - } } ] \ No newline at end of file diff --git a/assets/themes/cave-dark.json b/assets/themes/cave-dark.json new file mode 100644 index 0000000000000000000000000000000000000000..f0cb3746326a37474de58d91f6c44670114133b2 --- /dev/null +++ b/assets/themes/cave-dark.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#26232a", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "weight": "bold", + "size": 14 + }, + "background": "#5852607a" + }, + "border": { + "color": "#19171c", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#7e7887", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#19171c", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#7e7887", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14 + }, + "border": { + "color": "#26232a", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#26232a", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#26232a", + "icon_close": "#8b8792", + "icon_close_active": "#efecf4", + "icon_conflict": "#a06e3b", + "icon_dirty": "#576ddb", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "border": { + "color": "#19171c", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#19171c", + "icon_close": "#8b8792", + "icon_close_active": "#efecf4", + "icon_conflict": "#a06e3b", + "icon_dirty": "#576ddb", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#efecf4", + "size": 14 + }, + "border": { + "color": "#19171c", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#26232a", + "border": { + "color": "#19171c", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#8b8792", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#efecf4", + "icon_size": 18 + }, + "resize_handle": { + "background": "#19171c", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#26232a", + "border": { + "color": "#19171c", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#8b8792", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#efecf4", + "icon_size": 18 + }, + "resize_handle": { + "background": "#19171c", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#26232a", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#19171c", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#26232a", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#19171c", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 12, + "border": { + "color": "#19171c", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#efecf4", + "size": 12, + "border": { + "color": "#19171c", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#8b8792", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#8b8792" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#58526052", + "color": "#8b8792" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#58526052", + "color": "#efecf4" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#5852607a", + "color": "#efecf4" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#19171c", + "border": { + "color": "#26232a", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#efecf4", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#efecf4", + "background": "#19171c", + "active_line_background": "#efecf412", + "code_actions_indicator": "#8b8792", + "diff_background_deleted": "#be4678", + "diff_background_inserted": "#2a9292", + "document_highlight_read_background": "#19171c1f", + "document_highlight_write_background": "#19171c29", + "error_color": "#be4678", + "gutter_background": "#19171c", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#efecf41f", + "line_number": "#7e7887", + "line_number_active": "#efecf4", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "guest_selections": [ + { + "cursor": "#2a9292", + "selection": "#2a92923d" + }, + { + "cursor": "#bf40bf", + "selection": "#bf40bf3d" + }, + { + "cursor": "#aa573c", + "selection": "#aa573c3d" + }, + { + "cursor": "#955ae7", + "selection": "#955ae73d" + }, + { + "cursor": "#398bc6", + "selection": "#398bc63d" + }, + { + "cursor": "#be4678", + "selection": "#be46783d" + }, + { + "cursor": "#a06e3b", + "selection": "#a06e3b3d" + } + ], + "autocomplete": { + "background": "#19171c", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#26232a", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#26232a" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#576ddb", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#26232a" + } + }, + "diagnostic_header": { + "background": "#26232a", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#26232a", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#efecf412", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#be4678", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#be4678", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#19171c", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#efecf4", + "weight": "normal" + }, + "comment": { + "color": "#8b8792", + "weight": "normal" + }, + "punctuation": { + "color": "#8b8792", + "weight": "normal" + }, + "constant": { + "color": "#7e7887", + "weight": "normal" + }, + "keyword": { + "color": "#576ddb", + "weight": "normal" + }, + "function": { + "color": "#a06e3b", + "weight": "normal" + }, + "type": { + "color": "#398bc6", + "weight": "normal" + }, + "variant": { + "color": "#576ddb", + "weight": "normal" + }, + "property": { + "color": "#576ddb", + "weight": "normal" + }, + "enum": { + "color": "#aa573c", + "weight": "normal" + }, + "operator": { + "color": "#aa573c", + "weight": "normal" + }, + "string": { + "color": "#aa573c", + "weight": "normal" + }, + "number": { + "color": "#2a9292", + "weight": "normal" + }, + "boolean": { + "color": "#2a9292", + "weight": "normal" + }, + "predictive": { + "color": "#8b8792", + "weight": "normal" + }, + "title": { + "color": "#a06e3b", + "weight": "bold" + }, + "emphasis": { + "color": "#576ddb", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#576ddb", + "weight": "bold" + }, + "link_uri": { + "color": "#2a9292", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#aa573c", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 12 + }, + "corner_radius": 4, + "background": "#19171c", + "border": { + "color": "#26232a", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#8b8792", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#58526052", + "icon_color": "#8b8792", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#8b8792", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#58526052", + "icon_color": "#8b8792", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#e2dfe7", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#58526052", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#e2dfe7", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#58526052", + "corner_radius": 6 + }, + "menu": { + "background": "#19171c", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#19171c", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#8b8792", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#e2dfe7", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#e2dfe7", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#8b8792", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#19171c", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "border": { + "color": "#26232a", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#655f6d", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#26232a", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#58526052", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#955ae780", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#efecf4", + "size": 14, + "background": "#655f6d", + "corner_radius": 4, + "border": { + "color": "#655f6d", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#efecf4", + "size": 14, + "background": "#655f6d", + "corner_radius": 4, + "border": { + "color": "#655f6d", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#19171c", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#efecf4", + "size": 14 + }, + "border": { + "color": "#26232a", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#efecf4", + "size": 14, + "background": "#26232a", + "corner_radius": 4, + "border": { + "color": "#655f6d", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#19171c", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#7e7887", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#efecf4", + "size": 14 + }, + "border": { + "color": "#be4678", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#8b8792", + "size": 14, + "background": "#26232a", + "corner_radius": 4, + "border": { + "color": "#26232a", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#e2dfe7", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#8b8792", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/assets/themes/cave-light.json b/assets/themes/cave-light.json new file mode 100644 index 0000000000000000000000000000000000000000..aa062d478695e7231c71500cdb2e072602f750ca --- /dev/null +++ b/assets/themes/cave-light.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#e2dfe7", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "weight": "bold", + "size": 14 + }, + "background": "#8b87922e" + }, + "border": { + "color": "#efecf4", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#655f6d", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#efecf4", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#655f6d", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14 + }, + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#e2dfe7", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#e2dfe7", + "icon_close": "#585260", + "icon_close_active": "#19171c", + "icon_conflict": "#a06e3b", + "icon_dirty": "#576ddb", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "border": { + "color": "#efecf4", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#efecf4", + "icon_close": "#585260", + "icon_close_active": "#19171c", + "icon_conflict": "#a06e3b", + "icon_dirty": "#576ddb", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#19171c", + "size": 14 + }, + "border": { + "color": "#efecf4", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#e2dfe7", + "border": { + "color": "#efecf4", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#585260", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#19171c", + "icon_size": 18 + }, + "resize_handle": { + "background": "#efecf4", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#e2dfe7", + "border": { + "color": "#efecf4", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#585260", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#19171c", + "icon_size": 18 + }, + "resize_handle": { + "background": "#efecf4", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#e2dfe7", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#efecf4", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#e2dfe7", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#efecf4", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#585260", + "size": 12, + "border": { + "color": "#efecf4", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#19171c", + "size": 12, + "border": { + "color": "#efecf4", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#585260", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#585260" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#8b87921f", + "color": "#585260" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#8b87921f", + "color": "#19171c" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#8b87922e", + "color": "#19171c" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#efecf4", + "border": { + "color": "#e2dfe7", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#19171c", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#19171c", + "background": "#efecf4", + "active_line_background": "#19171c12", + "code_actions_indicator": "#585260", + "diff_background_deleted": "#be4678", + "diff_background_inserted": "#2a9292", + "document_highlight_read_background": "#efecf41f", + "document_highlight_write_background": "#efecf429", + "error_color": "#be4678", + "gutter_background": "#efecf4", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#19171c1f", + "line_number": "#655f6d", + "line_number_active": "#19171c", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "guest_selections": [ + { + "cursor": "#2a9292", + "selection": "#2a92923d" + }, + { + "cursor": "#bf40bf", + "selection": "#bf40bf3d" + }, + { + "cursor": "#aa573c", + "selection": "#aa573c3d" + }, + { + "cursor": "#955ae7", + "selection": "#955ae73d" + }, + { + "cursor": "#398bc6", + "selection": "#398bc63d" + }, + { + "cursor": "#be4678", + "selection": "#be46783d" + }, + { + "cursor": "#a06e3b", + "selection": "#a06e3b3d" + } + ], + "autocomplete": { + "background": "#efecf4", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#e2dfe7" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#576ddb", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#e2dfe7" + } + }, + "diagnostic_header": { + "background": "#e2dfe7", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#e2dfe7", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#19171c12", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#be4678", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#be4678", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#a06e3b", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#576ddb", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#efecf4", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#19171c", + "weight": "normal" + }, + "comment": { + "color": "#585260", + "weight": "normal" + }, + "punctuation": { + "color": "#585260", + "weight": "normal" + }, + "constant": { + "color": "#655f6d", + "weight": "normal" + }, + "keyword": { + "color": "#576ddb", + "weight": "normal" + }, + "function": { + "color": "#a06e3b", + "weight": "normal" + }, + "type": { + "color": "#398bc6", + "weight": "normal" + }, + "variant": { + "color": "#576ddb", + "weight": "normal" + }, + "property": { + "color": "#576ddb", + "weight": "normal" + }, + "enum": { + "color": "#aa573c", + "weight": "normal" + }, + "operator": { + "color": "#aa573c", + "weight": "normal" + }, + "string": { + "color": "#aa573c", + "weight": "normal" + }, + "number": { + "color": "#2a9292", + "weight": "normal" + }, + "boolean": { + "color": "#2a9292", + "weight": "normal" + }, + "predictive": { + "color": "#585260", + "weight": "normal" + }, + "title": { + "color": "#a06e3b", + "weight": "bold" + }, + "emphasis": { + "color": "#576ddb", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#576ddb", + "weight": "bold" + }, + "link_uri": { + "color": "#2a9292", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#aa573c", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#26232a", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#585260", + "size": 12 + }, + "corner_radius": 4, + "background": "#efecf4", + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#585260", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#585260", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#8b87921f", + "icon_color": "#585260", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#585260", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#585260", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#8b87921f", + "icon_color": "#585260", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#26232a", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#8b87921f", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#26232a", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#8b87921f", + "corner_radius": 6 + }, + "menu": { + "background": "#efecf4", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#efecf4", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#585260", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#26232a", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#26232a", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#585260", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#585260", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#efecf4", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#7e7887", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#26232a", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#e2dfe7", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#8b87921f", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#955ae780", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#19171c", + "size": 14, + "background": "#7e7887", + "corner_radius": 4, + "border": { + "color": "#7e7887", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#19171c", + "size": 14, + "background": "#7e7887", + "corner_radius": 4, + "border": { + "color": "#7e7887", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#efecf4", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#19171c", + "size": 14 + }, + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#19171c", + "size": 14, + "background": "#e2dfe7", + "corner_radius": 4, + "border": { + "color": "#7e7887", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#efecf4", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#655f6d", + "size": 14 + }, + "selection": { + "cursor": "#576ddb", + "selection": "#576ddb3d" + }, + "text": { + "family": "Zed Mono", + "color": "#19171c", + "size": 14 + }, + "border": { + "color": "#be4678", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#585260", + "size": 14, + "background": "#e2dfe7", + "corner_radius": 4, + "border": { + "color": "#e2dfe7", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#26232a", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#585260", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/assets/themes/dark.json b/assets/themes/dark.json index 5003d23d4dfc91f4ab3f19f27f73a119b4a6a669..2a371680f55fdfe701ec6400ac055bbb00705993 100644 --- a/assets/themes/dark.json +++ b/assets/themes/dark.json @@ -89,10 +89,6 @@ "top": 7 } }, - "margin": { - "bottom": 52, - "top": 52 - }, "shadow": { "blur": 16, "color": "#00000052", @@ -158,6 +154,13 @@ "right": 8 } }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, "left_sidebar": { "width": 30, "background": "#1c1c1c", @@ -255,8 +258,9 @@ "avatar_width": 18, "height": 32, "background": "#2b2b2b", - "share_icon_color": "#9c9c9c", - "share_icon_active_color": "#2472f2", + "padding": { + "left": 80 + }, "title": { "family": "Zed Sans", "color": "#f1f1f1", @@ -321,10 +325,48 @@ "right": 4 } }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#9c9c9c" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#323232", + "color": "#9c9c9c" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#323232", + "color": "#ffffff" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#1c1c1c", + "color": "#ffffff" + }, "outdated_warning": { "family": "Zed Sans", "color": "#f7bb57", - "size": 13 + "size": 13, + "margin": { + "right": 6 + } } }, "toolbar": { @@ -689,33 +731,88 @@ } }, "syntax": { - "keyword": "#4f8ff7", - "function": "#f9da82", - "string": "#f99d5f", - "type": "#3eeeda", - "number": "#aeef4b", - "comment": "#aaaaaa", - "property": "#4f8ff7", - "variant": "#53c1f5", - "constant": "#d5d5d5", + "primary": { + "color": "#d5d5d5", + "weight": "normal" + }, + "comment": { + "color": "#aaaaaa", + "weight": "normal" + }, + "punctuation": { + "color": "#c6c6c6", + "weight": "normal" + }, + "constant": { + "color": "#d5d5d5", + "weight": "normal" + }, + "keyword": { + "color": "#4f8ff7", + "weight": "normal" + }, + "function": { + "color": "#f9da82", + "weight": "normal" + }, + "type": { + "color": "#3eeeda", + "weight": "normal" + }, + "variant": { + "color": "#53c1f5", + "weight": "normal" + }, + "property": { + "color": "#4f8ff7", + "weight": "normal" + }, + "enum": { + "color": "#ee670a", + "weight": "normal" + }, + "operator": { + "color": "#ee670a", + "weight": "normal" + }, + "string": { + "color": "#f99d5f", + "weight": "normal" + }, + "number": { + "color": "#aeef4b", + "weight": "normal" + }, + "boolean": { + "color": "#aeef4b", + "weight": "normal" + }, + "predictive": { + "color": "#808080", + "weight": "normal" + }, "title": { "color": "#de900c", "weight": "bold" }, - "emphasis": "#4f8ff7", - "emphasis_strong": { + "emphasis": { + "color": "#4f8ff7", + "weight": "normal" + }, + "emphasis.strong": { "color": "#4f8ff7", "weight": "bold" }, "link_uri": { "color": "#79ba16", + "weight": "normal", "underline": true }, "link_text": { "color": "#ee670a", + "weight": "normal", "italic": true - }, - "list_marker": "#c6c6c6" + } } }, "project_diagnostics": { diff --git a/assets/themes/light.json b/assets/themes/light.json index 5a370f4aa2b83b348f021beca379d499f01054f3..8d56526e20a936eb4f04338d26b4a1336b69972e 100644 --- a/assets/themes/light.json +++ b/assets/themes/light.json @@ -89,10 +89,6 @@ "top": 7 } }, - "margin": { - "bottom": 52, - "top": 52 - }, "shadow": { "blur": 16, "color": "#0000001f", @@ -158,6 +154,13 @@ "right": 8 } }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, "left_sidebar": { "width": 30, "background": "#f8f8f8", @@ -255,8 +258,9 @@ "avatar_width": 18, "height": 32, "background": "#eaeaea", - "share_icon_color": "#717171", - "share_icon_active_color": "#484bed", + "padding": { + "left": 80 + }, "title": { "family": "Zed Sans", "color": "#2b2b2b", @@ -321,10 +325,48 @@ "right": 4 } }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#717171" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#e3e3e3", + "color": "#717171" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#e3e3e3", + "color": "#000000" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#d5d5d5", + "color": "#000000" + }, "outdated_warning": { "family": "Zed Sans", "color": "#d3a20b", - "size": 13 + "size": 13, + "margin": { + "right": 6 + } } }, "toolbar": { @@ -689,33 +731,88 @@ } }, "syntax": { - "keyword": "#1819a1", - "function": "#bb550e", - "string": "#eb2d2d", - "type": "#a8820e", - "number": "#484bed", - "comment": "#717171", - "property": "#106c4e", - "variant": "#97142a", - "constant": "#1c1c1c", + "primary": { + "color": "#1c1c1c", + "weight": "normal" + }, + "comment": { + "color": "#717171", + "weight": "normal" + }, + "punctuation": { + "color": "#555555", + "weight": "normal" + }, + "constant": { + "color": "#1c1c1c", + "weight": "normal" + }, + "keyword": { + "color": "#1819a1", + "weight": "normal" + }, + "function": { + "color": "#bb550e", + "weight": "normal" + }, + "type": { + "color": "#a8820e", + "weight": "normal" + }, + "variant": { + "color": "#97142a", + "weight": "normal" + }, + "property": { + "color": "#106c4e", + "weight": "normal" + }, + "enum": { + "color": "#eb2d2d", + "weight": "normal" + }, + "operator": { + "color": "#eb2d2d", + "weight": "normal" + }, + "string": { + "color": "#eb2d2d", + "weight": "normal" + }, + "number": { + "color": "#484bed", + "weight": "normal" + }, + "boolean": { + "color": "#eb2d2d", + "weight": "normal" + }, + "predictive": { + "color": "#808080", + "weight": "normal" + }, "title": { "color": "#1096d3", "weight": "bold" }, - "emphasis": "#484bed", - "emphasis_strong": { + "emphasis": { + "color": "#484bed", + "weight": "normal" + }, + "emphasis.strong": { "color": "#484bed", "weight": "bold" }, "link_uri": { "color": "#79ba16", + "weight": "normal", "underline": true }, "link_text": { "color": "#eb2d2d", + "weight": "normal", "italic": true - }, - "list_marker": "#555555" + } } }, "project_diagnostics": { diff --git a/assets/themes/solarized-dark.json b/assets/themes/solarized-dark.json new file mode 100644 index 0000000000000000000000000000000000000000..bd73ab934e1955a41016bd7bc42ec6567b8382ed --- /dev/null +++ b/assets/themes/solarized-dark.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#073642", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "weight": "bold", + "size": 14 + }, + "background": "#586e757a" + }, + "border": { + "color": "#002b36", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#839496", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#002b36", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#839496", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14 + }, + "border": { + "color": "#073642", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#073642", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#073642", + "icon_close": "#93a1a1", + "icon_close_active": "#fdf6e3", + "icon_conflict": "#b58900", + "icon_dirty": "#268bd2", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "border": { + "color": "#002b36", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#002b36", + "icon_close": "#93a1a1", + "icon_close_active": "#fdf6e3", + "icon_conflict": "#b58900", + "icon_dirty": "#268bd2", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#fdf6e3", + "size": 14 + }, + "border": { + "color": "#002b36", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#073642", + "border": { + "color": "#002b36", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#93a1a1", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#fdf6e3", + "icon_size": 18 + }, + "resize_handle": { + "background": "#002b36", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#073642", + "border": { + "color": "#002b36", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#93a1a1", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#fdf6e3", + "icon_size": 18 + }, + "resize_handle": { + "background": "#002b36", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#073642", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#002b36", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#073642", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#002b36", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 12, + "border": { + "color": "#002b36", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#fdf6e3", + "size": 12, + "border": { + "color": "#002b36", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#93a1a1", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#93a1a1" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#586e7552", + "color": "#93a1a1" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#586e7552", + "color": "#fdf6e3" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#586e757a", + "color": "#fdf6e3" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#b58900", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#002b36", + "border": { + "color": "#073642", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#fdf6e3", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#fdf6e3", + "background": "#002b36", + "active_line_background": "#fdf6e312", + "code_actions_indicator": "#93a1a1", + "diff_background_deleted": "#dc322f", + "diff_background_inserted": "#859900", + "document_highlight_read_background": "#002b361f", + "document_highlight_write_background": "#002b3629", + "error_color": "#dc322f", + "gutter_background": "#002b36", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#fdf6e31f", + "line_number": "#839496", + "line_number_active": "#fdf6e3", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "guest_selections": [ + { + "cursor": "#859900", + "selection": "#8599003d" + }, + { + "cursor": "#d33682", + "selection": "#d336823d" + }, + { + "cursor": "#cb4b16", + "selection": "#cb4b163d" + }, + { + "cursor": "#6c71c4", + "selection": "#6c71c43d" + }, + { + "cursor": "#2aa198", + "selection": "#2aa1983d" + }, + { + "cursor": "#dc322f", + "selection": "#dc322f3d" + }, + { + "cursor": "#b58900", + "selection": "#b589003d" + } + ], + "autocomplete": { + "background": "#002b36", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#073642", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#073642" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#268bd2", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#073642" + } + }, + "diagnostic_header": { + "background": "#073642", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#073642", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#fdf6e312", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#dc322f", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#dc322f", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#b58900", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#b58900", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#002b36", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#fdf6e3", + "weight": "normal" + }, + "comment": { + "color": "#93a1a1", + "weight": "normal" + }, + "punctuation": { + "color": "#93a1a1", + "weight": "normal" + }, + "constant": { + "color": "#839496", + "weight": "normal" + }, + "keyword": { + "color": "#268bd2", + "weight": "normal" + }, + "function": { + "color": "#b58900", + "weight": "normal" + }, + "type": { + "color": "#2aa198", + "weight": "normal" + }, + "variant": { + "color": "#268bd2", + "weight": "normal" + }, + "property": { + "color": "#268bd2", + "weight": "normal" + }, + "enum": { + "color": "#cb4b16", + "weight": "normal" + }, + "operator": { + "color": "#cb4b16", + "weight": "normal" + }, + "string": { + "color": "#cb4b16", + "weight": "normal" + }, + "number": { + "color": "#859900", + "weight": "normal" + }, + "boolean": { + "color": "#859900", + "weight": "normal" + }, + "predictive": { + "color": "#93a1a1", + "weight": "normal" + }, + "title": { + "color": "#b58900", + "weight": "bold" + }, + "emphasis": { + "color": "#268bd2", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#268bd2", + "weight": "bold" + }, + "link_uri": { + "color": "#859900", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#cb4b16", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 12 + }, + "corner_radius": 4, + "background": "#002b36", + "border": { + "color": "#073642", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#93a1a1", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#586e7552", + "icon_color": "#93a1a1", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#93a1a1", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#586e7552", + "icon_color": "#93a1a1", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#eee8d5", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#586e7552", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#eee8d5", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#586e7552", + "corner_radius": 6 + }, + "menu": { + "background": "#002b36", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#002b36", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#93a1a1", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#eee8d5", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#eee8d5", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#93a1a1", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#002b36", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#839496", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "border": { + "color": "#073642", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#657b83", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#839496", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#073642", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#586e7552", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#839496", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#839496", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#6c71c480", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#fdf6e3", + "size": 14, + "background": "#657b83", + "corner_radius": 4, + "border": { + "color": "#657b83", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#fdf6e3", + "size": 14, + "background": "#657b83", + "corner_radius": 4, + "border": { + "color": "#657b83", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#002b36", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#839496", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#fdf6e3", + "size": 14 + }, + "border": { + "color": "#073642", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#fdf6e3", + "size": 14, + "background": "#073642", + "corner_radius": 4, + "border": { + "color": "#657b83", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#002b36", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#839496", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#fdf6e3", + "size": 14 + }, + "border": { + "color": "#dc322f", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#93a1a1", + "size": 14, + "background": "#073642", + "corner_radius": 4, + "border": { + "color": "#073642", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#eee8d5", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#93a1a1", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/assets/themes/solarized-light.json b/assets/themes/solarized-light.json new file mode 100644 index 0000000000000000000000000000000000000000..35de751a2b211e9cc68e25869eb7235f2e34fb9f --- /dev/null +++ b/assets/themes/solarized-light.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#eee8d5", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "weight": "bold", + "size": 14 + }, + "background": "#93a1a12e" + }, + "border": { + "color": "#fdf6e3", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#657b83", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#fdf6e3", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#657b83", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#073642", + "size": 14 + }, + "border": { + "color": "#eee8d5", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#eee8d5", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#eee8d5", + "icon_close": "#586e75", + "icon_close_active": "#002b36", + "icon_conflict": "#b58900", + "icon_dirty": "#268bd2", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "border": { + "color": "#fdf6e3", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#fdf6e3", + "icon_close": "#586e75", + "icon_close_active": "#002b36", + "icon_conflict": "#b58900", + "icon_dirty": "#268bd2", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#002b36", + "size": 14 + }, + "border": { + "color": "#fdf6e3", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#eee8d5", + "border": { + "color": "#fdf6e3", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#586e75", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#002b36", + "icon_size": 18 + }, + "resize_handle": { + "background": "#fdf6e3", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#eee8d5", + "border": { + "color": "#fdf6e3", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#586e75", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#002b36", + "icon_size": 18 + }, + "resize_handle": { + "background": "#fdf6e3", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#eee8d5", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#eee8d5", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#fdf6e3", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#586e75", + "size": 12, + "border": { + "color": "#fdf6e3", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#002b36", + "size": 12, + "border": { + "color": "#fdf6e3", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#586e75", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#586e75" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#93a1a11f", + "color": "#586e75" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#93a1a11f", + "color": "#002b36" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#93a1a12e", + "color": "#002b36" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#b58900", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#fdf6e3", + "border": { + "color": "#eee8d5", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#002b36", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#002b36", + "background": "#fdf6e3", + "active_line_background": "#002b3612", + "code_actions_indicator": "#586e75", + "diff_background_deleted": "#dc322f", + "diff_background_inserted": "#859900", + "document_highlight_read_background": "#fdf6e31f", + "document_highlight_write_background": "#fdf6e329", + "error_color": "#dc322f", + "gutter_background": "#fdf6e3", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#002b361f", + "line_number": "#657b83", + "line_number_active": "#002b36", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "guest_selections": [ + { + "cursor": "#859900", + "selection": "#8599003d" + }, + { + "cursor": "#d33682", + "selection": "#d336823d" + }, + { + "cursor": "#cb4b16", + "selection": "#cb4b163d" + }, + { + "cursor": "#6c71c4", + "selection": "#6c71c43d" + }, + { + "cursor": "#2aa198", + "selection": "#2aa1983d" + }, + { + "cursor": "#dc322f", + "selection": "#dc322f3d" + }, + { + "cursor": "#b58900", + "selection": "#b589003d" + } + ], + "autocomplete": { + "background": "#fdf6e3", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#eee8d5", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#eee8d5" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#268bd2", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#eee8d5" + } + }, + "diagnostic_header": { + "background": "#eee8d5", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#eee8d5", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#073642", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#002b3612", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#073642", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#dc322f", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#dc322f", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#b58900", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#b58900", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#268bd2", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#fdf6e3", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#002b36", + "weight": "normal" + }, + "comment": { + "color": "#586e75", + "weight": "normal" + }, + "punctuation": { + "color": "#586e75", + "weight": "normal" + }, + "constant": { + "color": "#657b83", + "weight": "normal" + }, + "keyword": { + "color": "#268bd2", + "weight": "normal" + }, + "function": { + "color": "#b58900", + "weight": "normal" + }, + "type": { + "color": "#2aa198", + "weight": "normal" + }, + "variant": { + "color": "#268bd2", + "weight": "normal" + }, + "property": { + "color": "#268bd2", + "weight": "normal" + }, + "enum": { + "color": "#cb4b16", + "weight": "normal" + }, + "operator": { + "color": "#cb4b16", + "weight": "normal" + }, + "string": { + "color": "#cb4b16", + "weight": "normal" + }, + "number": { + "color": "#859900", + "weight": "normal" + }, + "boolean": { + "color": "#859900", + "weight": "normal" + }, + "predictive": { + "color": "#586e75", + "weight": "normal" + }, + "title": { + "color": "#b58900", + "weight": "bold" + }, + "emphasis": { + "color": "#268bd2", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#268bd2", + "weight": "bold" + }, + "link_uri": { + "color": "#859900", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#cb4b16", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#073642", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#586e75", + "size": 12 + }, + "corner_radius": 4, + "background": "#fdf6e3", + "border": { + "color": "#eee8d5", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#586e75", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#93a1a11f", + "icon_color": "#586e75", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#586e75", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#073642", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#93a1a11f", + "icon_color": "#586e75", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#073642", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#073642", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#93a1a11f", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#073642", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#93a1a11f", + "corner_radius": 6 + }, + "menu": { + "background": "#fdf6e3", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#fdf6e3", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#586e75", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#073642", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#073642", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#586e75", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#fdf6e3", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#073642", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "border": { + "color": "#eee8d5", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#839496", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#073642", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#eee8d5", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#93a1a11f", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#6c71c480", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#002b36", + "size": 14, + "background": "#839496", + "corner_radius": 4, + "border": { + "color": "#839496", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#002b36", + "size": 14, + "background": "#839496", + "corner_radius": 4, + "border": { + "color": "#839496", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#fdf6e3", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#002b36", + "size": 14 + }, + "border": { + "color": "#eee8d5", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#002b36", + "size": 14, + "background": "#eee8d5", + "corner_radius": 4, + "border": { + "color": "#839496", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#fdf6e3", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#657b83", + "size": 14 + }, + "selection": { + "cursor": "#268bd2", + "selection": "#268bd23d" + }, + "text": { + "family": "Zed Mono", + "color": "#002b36", + "size": 14 + }, + "border": { + "color": "#dc322f", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#586e75", + "size": 14, + "background": "#eee8d5", + "corner_radius": 4, + "border": { + "color": "#eee8d5", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#073642", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#586e75", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/assets/themes/sulphurpool-dark.json b/assets/themes/sulphurpool-dark.json new file mode 100644 index 0000000000000000000000000000000000000000..20123449bb893eb718513bb97cfbd0e49e0f0d97 --- /dev/null +++ b/assets/themes/sulphurpool-dark.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#293256", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "weight": "bold", + "size": 14 + }, + "background": "#5e66877a" + }, + "border": { + "color": "#202746", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#898ea4", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#202746", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#898ea4", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14 + }, + "border": { + "color": "#293256", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#293256", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#293256", + "icon_close": "#979db4", + "icon_close_active": "#f5f7ff", + "icon_conflict": "#c08b30", + "icon_dirty": "#3d8fd1", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "border": { + "color": "#202746", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#202746", + "icon_close": "#979db4", + "icon_close_active": "#f5f7ff", + "icon_conflict": "#c08b30", + "icon_dirty": "#3d8fd1", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#f5f7ff", + "size": 14 + }, + "border": { + "color": "#202746", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#293256", + "border": { + "color": "#202746", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#979db4", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#f5f7ff", + "icon_size": 18 + }, + "resize_handle": { + "background": "#202746", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#293256", + "border": { + "color": "#202746", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#979db4", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#f5f7ff", + "icon_size": 18 + }, + "resize_handle": { + "background": "#202746", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#293256", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#202746", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#293256", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#202746", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#979db4", + "size": 12, + "border": { + "color": "#202746", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#f5f7ff", + "size": 12, + "border": { + "color": "#202746", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#979db4", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#979db4" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#5e668752", + "color": "#979db4" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#5e668752", + "color": "#f5f7ff" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#5e66877a", + "color": "#f5f7ff" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#202746", + "border": { + "color": "#293256", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#f5f7ff", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#f5f7ff", + "background": "#202746", + "active_line_background": "#f5f7ff12", + "code_actions_indicator": "#979db4", + "diff_background_deleted": "#c94922", + "diff_background_inserted": "#ac9739", + "document_highlight_read_background": "#2027461f", + "document_highlight_write_background": "#20274629", + "error_color": "#c94922", + "gutter_background": "#202746", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#f5f7ff1f", + "line_number": "#898ea4", + "line_number_active": "#f5f7ff", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "guest_selections": [ + { + "cursor": "#ac9739", + "selection": "#ac97393d" + }, + { + "cursor": "#9c637a", + "selection": "#9c637a3d" + }, + { + "cursor": "#c76b29", + "selection": "#c76b293d" + }, + { + "cursor": "#6679cc", + "selection": "#6679cc3d" + }, + { + "cursor": "#22a2c9", + "selection": "#22a2c93d" + }, + { + "cursor": "#c94922", + "selection": "#c949223d" + }, + { + "cursor": "#c08b30", + "selection": "#c08b303d" + } + ], + "autocomplete": { + "background": "#202746", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#293256", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#293256" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#3d8fd1", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#293256" + } + }, + "diagnostic_header": { + "background": "#293256", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#293256", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#f5f7ff12", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#c94922", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#c94922", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#202746", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#f5f7ff", + "weight": "normal" + }, + "comment": { + "color": "#979db4", + "weight": "normal" + }, + "punctuation": { + "color": "#979db4", + "weight": "normal" + }, + "constant": { + "color": "#898ea4", + "weight": "normal" + }, + "keyword": { + "color": "#3d8fd1", + "weight": "normal" + }, + "function": { + "color": "#c08b30", + "weight": "normal" + }, + "type": { + "color": "#22a2c9", + "weight": "normal" + }, + "variant": { + "color": "#3d8fd1", + "weight": "normal" + }, + "property": { + "color": "#3d8fd1", + "weight": "normal" + }, + "enum": { + "color": "#c76b29", + "weight": "normal" + }, + "operator": { + "color": "#c76b29", + "weight": "normal" + }, + "string": { + "color": "#c76b29", + "weight": "normal" + }, + "number": { + "color": "#ac9739", + "weight": "normal" + }, + "boolean": { + "color": "#ac9739", + "weight": "normal" + }, + "predictive": { + "color": "#979db4", + "weight": "normal" + }, + "title": { + "color": "#c08b30", + "weight": "bold" + }, + "emphasis": { + "color": "#3d8fd1", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#3d8fd1", + "weight": "bold" + }, + "link_uri": { + "color": "#ac9739", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#c76b29", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#979db4", + "size": 12 + }, + "corner_radius": 4, + "background": "#202746", + "border": { + "color": "#293256", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#979db4", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#5e668752", + "icon_color": "#979db4", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#979db4", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#5e668752", + "icon_color": "#979db4", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#dfe2f1", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#5e668752", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#dfe2f1", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#5e668752", + "corner_radius": 6 + }, + "menu": { + "background": "#202746", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#202746", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#00000052", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#979db4", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#dfe2f1", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#dfe2f1", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#979db4", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#202746", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "border": { + "color": "#293256", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#6b7394", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#293256", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#5e668752", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#6679cc80", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#f5f7ff", + "size": 14, + "background": "#6b7394", + "corner_radius": 4, + "border": { + "color": "#6b7394", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#f5f7ff", + "size": 14, + "background": "#6b7394", + "corner_radius": 4, + "border": { + "color": "#6b7394", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#202746", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#f5f7ff", + "size": 14 + }, + "border": { + "color": "#293256", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#f5f7ff", + "size": 14, + "background": "#293256", + "corner_radius": 4, + "border": { + "color": "#6b7394", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#202746", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#898ea4", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#f5f7ff", + "size": 14 + }, + "border": { + "color": "#c94922", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#979db4", + "size": 14, + "background": "#293256", + "corner_radius": 4, + "border": { + "color": "#293256", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#dfe2f1", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#979db4", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/assets/themes/sulphurpool-light.json b/assets/themes/sulphurpool-light.json new file mode 100644 index 0000000000000000000000000000000000000000..9bebd8203658ebcb08cb250e92e106f539b575ac --- /dev/null +++ b/assets/themes/sulphurpool-light.json @@ -0,0 +1,1435 @@ +{ + "selector": { + "background": "#dfe2f1", + "corner_radius": 8, + "padding": 8, + "item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "weight": "bold", + "size": 14 + } + }, + "active_item": { + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 4 + }, + "corner_radius": 8, + "text": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "weight": "bold", + "size": 14 + }, + "background": "#979db42e" + }, + "border": { + "color": "#f5f7ff", + "width": 1 + }, + "empty": { + "text": { + "family": "Zed Sans", + "color": "#6b7394", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 12, + "right": 12, + "top": 8 + } + }, + "input_editor": { + "background": "#f5f7ff", + "corner_radius": 8, + "placeholder_text": { + "family": "Zed Sans", + "color": "#6b7394", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#293256", + "size": 14 + }, + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 16, + "right": 16, + "top": 7 + } + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + }, + "workspace": { + "background": "#dfe2f1", + "leader_border_opacity": 0.7, + "leader_border_width": 2, + "tab": { + "height": 32, + "background": "#dfe2f1", + "icon_close": "#5e6687", + "icon_close_active": "#202746", + "icon_conflict": "#c08b30", + "icon_dirty": "#3d8fd1", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "border": { + "color": "#f5f7ff", + "width": 1, + "left": true, + "bottom": true, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "active_tab": { + "height": 32, + "background": "#f5f7ff", + "icon_close": "#5e6687", + "icon_close_active": "#202746", + "icon_conflict": "#c08b30", + "icon_dirty": "#3d8fd1", + "icon_width": 8, + "spacing": 8, + "text": { + "family": "Zed Sans", + "color": "#202746", + "size": 14 + }, + "border": { + "color": "#f5f7ff", + "width": 1, + "left": true, + "bottom": false, + "overlay": true + }, + "padding": { + "left": 8, + "right": 8 + } + }, + "modal": { + "margin": { + "bottom": 52, + "top": 52 + }, + "cursor": "Arrow" + }, + "left_sidebar": { + "width": 30, + "background": "#dfe2f1", + "border": { + "color": "#f5f7ff", + "width": 1, + "right": true + }, + "item": { + "height": 32, + "icon_color": "#5e6687", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#202746", + "icon_size": 18 + }, + "resize_handle": { + "background": "#f5f7ff", + "padding": { + "left": 1 + } + } + }, + "right_sidebar": { + "width": 30, + "background": "#dfe2f1", + "border": { + "color": "#f5f7ff", + "width": 1, + "left": true + }, + "item": { + "height": 32, + "icon_color": "#5e6687", + "icon_size": 18 + }, + "active_item": { + "height": 32, + "icon_color": "#202746", + "icon_size": 18 + }, + "resize_handle": { + "background": "#f5f7ff", + "padding": { + "left": 1 + } + } + }, + "pane_divider": { + "color": "#dfe2f1", + "width": 1 + }, + "status_bar": { + "height": 24, + "item_spacing": 8, + "padding": { + "left": 6, + "right": 6 + }, + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true, + "overlay": true + }, + "cursor_position": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "diagnostic_message": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "lsp_message": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "auto_update_progress_message": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "auto_update_done_message": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + } + }, + "titlebar": { + "avatar_width": 18, + "height": 32, + "background": "#dfe2f1", + "padding": { + "left": 80 + }, + "title": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "avatar": { + "corner_radius": 10, + "border": { + "color": "#00000088", + "width": 1 + } + }, + "avatar_ribbon": { + "height": 3, + "width": 12 + }, + "border": { + "color": "#f5f7ff", + "width": 1, + "bottom": true + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 12, + "border": { + "color": "#f5f7ff", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#202746", + "size": 12, + "border": { + "color": "#f5f7ff", + "width": 1 + }, + "corner_radius": 6, + "margin": { + "top": 1, + "right": 6 + }, + "padding": { + "left": 6, + "right": 6 + } + }, + "offline_icon": { + "color": "#5e6687", + "width": 16, + "padding": { + "right": 4 + } + }, + "share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "color": "#5e6687" + }, + "hovered_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#979db41f", + "color": "#5e6687" + }, + "hovered_active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#979db41f", + "color": "#202746" + }, + "active_share_icon": { + "margin": { + "top": 3, + "bottom": 2 + }, + "corner_radius": 6, + "background": "#979db42e", + "color": "#202746" + }, + "outdated_warning": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 13, + "margin": { + "right": 6 + } + } + }, + "toolbar": { + "height": 34, + "background": "#f5f7ff", + "border": { + "color": "#dfe2f1", + "width": 1, + "bottom": true + }, + "item_spacing": 8, + "padding": { + "left": 16, + "right": 8, + "top": 4, + "bottom": 4 + } + }, + "breadcrumbs": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "padding": { + "left": 6 + } + }, + "disconnected_overlay": { + "family": "Zed Sans", + "color": "#202746", + "size": 14, + "background": "#000000aa" + } + }, + "editor": { + "text_color": "#202746", + "background": "#f5f7ff", + "active_line_background": "#20274612", + "code_actions_indicator": "#5e6687", + "diff_background_deleted": "#c94922", + "diff_background_inserted": "#ac9739", + "document_highlight_read_background": "#f5f7ff1f", + "document_highlight_write_background": "#f5f7ff29", + "error_color": "#c94922", + "gutter_background": "#f5f7ff", + "gutter_padding_factor": 3.5, + "highlighted_line_background": "#2027461f", + "line_number": "#6b7394", + "line_number_active": "#202746", + "rename_fade": 0.6, + "unnecessary_code_fade": 0.5, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "guest_selections": [ + { + "cursor": "#ac9739", + "selection": "#ac97393d" + }, + { + "cursor": "#9c637a", + "selection": "#9c637a3d" + }, + { + "cursor": "#c76b29", + "selection": "#c76b293d" + }, + { + "cursor": "#6679cc", + "selection": "#6679cc3d" + }, + { + "cursor": "#22a2c9", + "selection": "#22a2c93d" + }, + { + "cursor": "#c94922", + "selection": "#c949223d" + }, + { + "cursor": "#c08b30", + "selection": "#c08b303d" + } + ], + "autocomplete": { + "background": "#f5f7ff", + "corner_radius": 8, + "padding": 4, + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + } + }, + "hovered_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#dfe2f1" + }, + "margin": { + "left": -14 + }, + "match_highlight": { + "family": "Zed Mono", + "color": "#3d8fd1", + "size": 14 + }, + "selected_item": { + "corner_radius": 6, + "padding": { + "bottom": 2, + "left": 6, + "right": 6, + "top": 2 + }, + "background": "#dfe2f1" + } + }, + "diagnostic_header": { + "background": "#dfe2f1", + "icon_width_factor": 1.5, + "text_scale_factor": 0.857, + "border": { + "color": "#dfe2f1", + "width": 1, + "bottom": true, + "top": true + }, + "code": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "margin": { + "left": 10 + } + }, + "message": { + "highlight_text": { + "family": "Zed Sans", + "color": "#293256", + "size": 14, + "weight": "bold" + }, + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + } + } + }, + "diagnostic_path_header": { + "background": "#20274612", + "text_scale_factor": 0.857, + "filename": { + "family": "Zed Mono", + "color": "#293256", + "size": 14 + }, + "path": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "margin": { + "left": 12 + } + } + }, + "error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#c94922", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#c94922", + "size": 14, + "weight": "bold" + } + } + }, + "warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#c08b30", + "size": 14, + "weight": "bold" + } + } + }, + "information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14, + "weight": "bold" + } + } + }, + "hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#3d8fd1", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_error_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_hint_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_information_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "weight": "bold" + } + } + }, + "invalid_warning_diagnostic": { + "text_scale_factor": 0.857, + "header": { + "border": { + "color": "#f5f7ff", + "width": 1, + "top": true + } + }, + "message": { + "text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "highlight_text": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "weight": "bold" + } + } + }, + "syntax": { + "primary": { + "color": "#202746", + "weight": "normal" + }, + "comment": { + "color": "#5e6687", + "weight": "normal" + }, + "punctuation": { + "color": "#5e6687", + "weight": "normal" + }, + "constant": { + "color": "#6b7394", + "weight": "normal" + }, + "keyword": { + "color": "#3d8fd1", + "weight": "normal" + }, + "function": { + "color": "#c08b30", + "weight": "normal" + }, + "type": { + "color": "#22a2c9", + "weight": "normal" + }, + "variant": { + "color": "#3d8fd1", + "weight": "normal" + }, + "property": { + "color": "#3d8fd1", + "weight": "normal" + }, + "enum": { + "color": "#c76b29", + "weight": "normal" + }, + "operator": { + "color": "#c76b29", + "weight": "normal" + }, + "string": { + "color": "#c76b29", + "weight": "normal" + }, + "number": { + "color": "#ac9739", + "weight": "normal" + }, + "boolean": { + "color": "#ac9739", + "weight": "normal" + }, + "predictive": { + "color": "#5e6687", + "weight": "normal" + }, + "title": { + "color": "#c08b30", + "weight": "bold" + }, + "emphasis": { + "color": "#3d8fd1", + "weight": "normal" + }, + "emphasis.strong": { + "color": "#3d8fd1", + "weight": "bold" + }, + "link_uri": { + "color": "#ac9739", + "weight": "normal", + "underline": true + }, + "link_text": { + "color": "#c76b29", + "weight": "normal", + "italic": true + } + } + }, + "project_diagnostics": { + "tab_icon_spacing": 4, + "tab_icon_width": 13, + "tab_summary_spacing": 10, + "empty_message": { + "family": "Zed Sans", + "color": "#293256", + "size": 18 + }, + "status_bar_item": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 10 + } + } + }, + "command_palette": { + "keystroke_spacing": 8, + "key": { + "text": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 12 + }, + "corner_radius": 4, + "background": "#f5f7ff", + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "padding": { + "top": 2, + "bottom": 2, + "left": 8, + "right": 8 + }, + "margin": { + "left": 2 + } + } + }, + "project_panel": { + "padding": { + "top": 6, + "left": 12 + }, + "entry": { + "height": 22, + "icon_color": "#5e6687", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14 + } + }, + "hovered_entry": { + "height": 22, + "background": "#979db41f", + "icon_color": "#5e6687", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14 + } + }, + "selected_entry": { + "height": 22, + "icon_color": "#5e6687", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#293256", + "size": 14 + } + }, + "hovered_selected_entry": { + "height": 22, + "background": "#979db41f", + "icon_color": "#5e6687", + "icon_size": 8, + "icon_spacing": 8, + "text": { + "family": "Zed Mono", + "color": "#293256", + "size": 14 + } + } + }, + "chat_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "channel_name": { + "family": "Zed Sans", + "color": "#293256", + "weight": "bold", + "size": 14 + }, + "channel_name_hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "padding": { + "right": 8 + } + }, + "channel_select": { + "header": { + "name": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "padding": { + "bottom": 4, + "left": 0 + }, + "hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "item": { + "name": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_item": { + "name": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#979db41f", + "corner_radius": 6 + }, + "active_item": { + "name": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 8 + } + }, + "corner_radius": 0 + }, + "hovered_active_item": { + "name": { + "family": "Zed Sans", + "color": "#293256", + "size": 14 + }, + "padding": 4, + "hash": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 8 + } + }, + "background": "#979db41f", + "corner_radius": 6 + }, + "menu": { + "background": "#f5f7ff", + "corner_radius": 6, + "padding": 4, + "border": { + "color": "#f5f7ff", + "width": 1 + }, + "shadow": { + "blur": 16, + "color": "#0000001f", + "offset": [ + 0, + 2 + ] + } + } + }, + "sign_in_prompt": { + "family": "Zed Sans", + "color": "#5e6687", + "underline": true, + "size": 14 + }, + "hovered_sign_in_prompt": { + "family": "Zed Sans", + "color": "#293256", + "underline": true, + "size": 14 + }, + "message": { + "body": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#293256", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "pending_message": { + "body": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "timestamp": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14 + }, + "padding": { + "bottom": 6 + }, + "sender": { + "family": "Zed Sans", + "color": "#5e6687", + "weight": "bold", + "size": 14, + "margin": { + "right": 8 + } + } + }, + "input_editor": { + "background": "#f5f7ff", + "corner_radius": 6, + "text": { + "family": "Zed Mono", + "color": "#293256", + "size": 14 + }, + "placeholder_text": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "padding": { + "bottom": 7, + "left": 8, + "right": 8, + "top": 7 + } + } + }, + "contacts_panel": { + "padding": { + "top": 12, + "left": 12, + "bottom": 12, + "right": 12 + }, + "host_row_height": 28, + "tree_branch_color": "#898ea4", + "tree_branch_width": 1, + "host_avatar": { + "corner_radius": 10, + "width": 18 + }, + "host_username": { + "family": "Zed Mono", + "color": "#293256", + "size": 14, + "padding": { + "left": 8 + } + }, + "project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#dfe2f1", + "corner_radius": 6 + }, + "hovered_shared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "background": "#979db41f", + "corner_radius": 6 + }, + "unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + } + }, + "hovered_unshared_project": { + "guest_avatar_spacing": 4, + "height": 24, + "guest_avatar": { + "corner_radius": 8, + "width": 14 + }, + "name": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14, + "margin": { + "right": 6 + } + }, + "padding": { + "left": 8 + }, + "corner_radius": 6 + } + }, + "search": { + "match_background": "#6679cc80", + "tab_icon_spacing": 8, + "tab_icon_width": 14, + "active_hovered_option_button": { + "family": "Zed Mono", + "color": "#202746", + "size": 14, + "background": "#898ea4", + "corner_radius": 4, + "border": { + "color": "#898ea4", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "active_option_button": { + "family": "Zed Mono", + "color": "#202746", + "size": 14, + "background": "#898ea4", + "corner_radius": 4, + "border": { + "color": "#898ea4", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "editor": { + "background": "#f5f7ff", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#202746", + "size": 14 + }, + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "hovered_option_button": { + "family": "Zed Mono", + "color": "#202746", + "size": 14, + "background": "#dfe2f1", + "corner_radius": 4, + "border": { + "color": "#898ea4", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "invalid_editor": { + "background": "#f5f7ff", + "corner_radius": 8, + "min_width": 200, + "max_width": 500, + "placeholder_text": { + "family": "Zed Mono", + "color": "#6b7394", + "size": 14 + }, + "selection": { + "cursor": "#3d8fd1", + "selection": "#3d8fd13d" + }, + "text": { + "family": "Zed Mono", + "color": "#202746", + "size": 14 + }, + "border": { + "color": "#c94922", + "width": 1 + }, + "margin": { + "right": 6 + }, + "padding": { + "top": 3, + "bottom": 3, + "left": 12, + "right": 8 + } + }, + "match_index": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "padding": 6 + }, + "option_button": { + "family": "Zed Mono", + "color": "#5e6687", + "size": 14, + "background": "#dfe2f1", + "corner_radius": 4, + "border": { + "color": "#dfe2f1", + "width": 1 + }, + "margin": { + "left": 2, + "right": 2 + }, + "padding": { + "bottom": 3, + "left": 8, + "right": 8, + "top": 3 + } + }, + "option_button_group": { + "padding": { + "left": 4, + "right": 4 + } + }, + "results_status": { + "family": "Zed Mono", + "color": "#293256", + "size": 18 + } + }, + "breadcrumbs": { + "family": "Zed Sans", + "color": "#5e6687", + "size": 14, + "padding": { + "left": 6 + } + } +} \ No newline at end of file diff --git a/crates/editor/src/display_map.rs b/crates/editor/src/display_map.rs index baf97a9b28d2a0736a62d6c014e1cd58ef65856d..d6e061ffc6e4f1dc2266832ec296733b435491a5 100644 --- a/crates/editor/src/display_map.rs +++ b/crates/editor/src/display_map.rs @@ -814,14 +814,20 @@ pub mod tests { DisplayPoint::new(0, 7) ); assert_eq!( - movement::up(&snapshot, DisplayPoint::new(1, 10), SelectionGoal::None), + movement::up( + &snapshot, + DisplayPoint::new(1, 10), + SelectionGoal::None, + false + ), (DisplayPoint::new(0, 7), SelectionGoal::Column(10)) ); assert_eq!( movement::down( &snapshot, DisplayPoint::new(0, 7), - SelectionGoal::Column(10) + SelectionGoal::Column(10), + false ), (DisplayPoint::new(1, 10), SelectionGoal::Column(10)) ); @@ -829,7 +835,8 @@ pub mod tests { movement::down( &snapshot, DisplayPoint::new(1, 10), - SelectionGoal::Column(10) + SelectionGoal::Column(10), + false ), (DisplayPoint::new(2, 4), SelectionGoal::Column(10)) ); diff --git a/crates/editor/src/editor.rs b/crates/editor/src/editor.rs index 9be20ba2ebc5197c62000508ef64175ebf6970f7..f60cf7eb9abaaff8001b57886e9becdc4f39ef44 100644 --- a/crates/editor/src/editor.rs +++ b/crates/editor/src/editor.rs @@ -1134,8 +1134,10 @@ impl Editor { } pub fn set_clip_at_line_ends(&mut self, clip: bool, cx: &mut ViewContext) { - self.display_map - .update(cx, |map, _| map.clip_at_line_ends = clip); + if self.display_map.read(cx).clip_at_line_ends != clip { + self.display_map + .update(cx, |map, _| map.clip_at_line_ends = clip); + } } pub fn set_keymap_context_layer(&mut self, context: gpui::keymap::Context) { @@ -3579,13 +3581,13 @@ impl Editor { if !selection.is_empty() { selection.goal = SelectionGoal::None; } - let (cursor, goal) = movement::up(&map, selection.start, selection.goal); + let (cursor, goal) = movement::up(&map, selection.start, selection.goal, false); selection.collapse_to(cursor, goal); }); } pub fn select_up(&mut self, _: &SelectUp, cx: &mut ViewContext) { - self.move_selection_heads(cx, movement::up) + self.move_selection_heads(cx, |map, head, goal| movement::up(map, head, goal, false)) } pub fn move_down(&mut self, _: &MoveDown, cx: &mut ViewContext) { @@ -3606,13 +3608,13 @@ impl Editor { if !selection.is_empty() { selection.goal = SelectionGoal::None; } - let (cursor, goal) = movement::down(&map, selection.end, selection.goal); + let (cursor, goal) = movement::down(&map, selection.end, selection.goal, false); selection.collapse_to(cursor, goal); }); } pub fn select_down(&mut self, _: &SelectDown, cx: &mut ViewContext) { - self.move_selection_heads(cx, movement::down) + self.move_selection_heads(cx, |map, head, goal| movement::down(map, head, goal, false)) } pub fn move_to_previous_word_start( diff --git a/crates/editor/src/element.rs b/crates/editor/src/element.rs index eb69463353f38676edbca44122fd1896d862c87a..28ef9e5af04f2f7c5be3cb2338edf27c87facac1 100644 --- a/crates/editor/src/element.rs +++ b/crates/editor/src/element.rs @@ -16,6 +16,7 @@ use gpui::{ PathBuilder, }, json::{self, ToJson}, + platform::CursorStyle, text_layout::{self, Line, RunStyle, TextLayoutCache}, AppContext, Axis, Border, Element, ElementBox, Event, EventContext, LayoutContext, MutableAppContext, PaintContext, Quad, Scene, SizeConstraint, ViewContext, WeakViewHandle, @@ -329,6 +330,7 @@ impl EditorElement { let content_origin = bounds.origin() + vec2f(layout.gutter_margin, 0.); cx.scene.push_layer(Some(bounds)); + cx.scene.push_cursor_style(bounds, CursorStyle::IBeam); for (range, color) in &layout.highlighted_ranges { self.paint_highlighted_range( diff --git a/crates/editor/src/movement.rs b/crates/editor/src/movement.rs index d5f0f480fb93e0f55f668cf2610d8260f994e544..1f4486739bd41a0764ec5ed02093e181d097d739 100644 --- a/crates/editor/src/movement.rs +++ b/crates/editor/src/movement.rs @@ -28,6 +28,7 @@ pub fn up( map: &DisplaySnapshot, start: DisplayPoint, goal: SelectionGoal, + preserve_column_at_start: bool, ) -> (DisplayPoint, SelectionGoal) { let mut goal_column = if let SelectionGoal::Column(column) = goal { column @@ -42,6 +43,8 @@ pub fn up( ); if point.row() < start.row() { *point.column_mut() = map.column_from_chars(point.row(), goal_column); + } else if preserve_column_at_start { + return (start, goal); } else { point = DisplayPoint::new(0, 0); goal_column = 0; @@ -63,6 +66,7 @@ pub fn down( map: &DisplaySnapshot, start: DisplayPoint, goal: SelectionGoal, + preserve_column_at_end: bool, ) -> (DisplayPoint, SelectionGoal) { let mut goal_column = if let SelectionGoal::Column(column) = goal { column @@ -74,6 +78,8 @@ pub fn down( let mut point = map.clip_point(DisplayPoint::new(next_row, 0), Bias::Right); if point.row() > start.row() { *point.column_mut() = map.column_from_chars(point.row(), goal_column); + } else if preserve_column_at_end { + return (start, goal); } else { point = map.max_point(); goal_column = map.column_to_chars(point.row(), point.column()) @@ -503,41 +509,81 @@ mod tests { // Can't move up into the first excerpt's header assert_eq!( - up(&snapshot, DisplayPoint::new(2, 2), SelectionGoal::Column(2)), + up( + &snapshot, + DisplayPoint::new(2, 2), + SelectionGoal::Column(2), + false + ), (DisplayPoint::new(2, 0), SelectionGoal::Column(0)), ); assert_eq!( - up(&snapshot, DisplayPoint::new(2, 0), SelectionGoal::None), + up( + &snapshot, + DisplayPoint::new(2, 0), + SelectionGoal::None, + false + ), (DisplayPoint::new(2, 0), SelectionGoal::Column(0)), ); // Move up and down within first excerpt assert_eq!( - up(&snapshot, DisplayPoint::new(3, 4), SelectionGoal::Column(4)), + up( + &snapshot, + DisplayPoint::new(3, 4), + SelectionGoal::Column(4), + false + ), (DisplayPoint::new(2, 3), SelectionGoal::Column(4)), ); assert_eq!( - down(&snapshot, DisplayPoint::new(2, 3), SelectionGoal::Column(4)), + down( + &snapshot, + DisplayPoint::new(2, 3), + SelectionGoal::Column(4), + false + ), (DisplayPoint::new(3, 4), SelectionGoal::Column(4)), ); // Move up and down across second excerpt's header assert_eq!( - up(&snapshot, DisplayPoint::new(6, 5), SelectionGoal::Column(5)), + up( + &snapshot, + DisplayPoint::new(6, 5), + SelectionGoal::Column(5), + false + ), (DisplayPoint::new(3, 4), SelectionGoal::Column(5)), ); assert_eq!( - down(&snapshot, DisplayPoint::new(3, 4), SelectionGoal::Column(5)), + down( + &snapshot, + DisplayPoint::new(3, 4), + SelectionGoal::Column(5), + false + ), (DisplayPoint::new(6, 5), SelectionGoal::Column(5)), ); // Can't move down off the end assert_eq!( - down(&snapshot, DisplayPoint::new(7, 0), SelectionGoal::Column(0)), + down( + &snapshot, + DisplayPoint::new(7, 0), + SelectionGoal::Column(0), + false + ), (DisplayPoint::new(7, 2), SelectionGoal::Column(2)), ); assert_eq!( - down(&snapshot, DisplayPoint::new(7, 2), SelectionGoal::Column(2)), + down( + &snapshot, + DisplayPoint::new(7, 2), + SelectionGoal::Column(2), + false + ), (DisplayPoint::new(7, 2), SelectionGoal::Column(2)), ); } diff --git a/crates/go_to_line/src/go_to_line.rs b/crates/go_to_line/src/go_to_line.rs index 7fa68a7675785a7a1e3c084dd70b6e83f980bb56..b8d9b5e5b19862adcdf10eda30222ab5a079f12e 100644 --- a/crates/go_to_line/src/go_to_line.rs +++ b/crates/go_to_line/src/go_to_line.rs @@ -161,29 +161,25 @@ impl View for GoToLine { self.max_point.row + 1 ); - Align::new( - ConstrainedBox::new( - Container::new( - Flex::new(Axis::Vertical) - .with_child( - Container::new(ChildView::new(&self.line_editor).boxed()) - .with_style(theme.input_editor.container) - .boxed(), - ) - .with_child( - Container::new(Label::new(label, theme.empty.label.clone()).boxed()) - .with_style(theme.empty.container) - .boxed(), - ) - .boxed(), - ) - .with_style(theme.container) - .boxed(), + ConstrainedBox::new( + Container::new( + Flex::new(Axis::Vertical) + .with_child( + Container::new(ChildView::new(&self.line_editor).boxed()) + .with_style(theme.input_editor.container) + .boxed(), + ) + .with_child( + Container::new(Label::new(label, theme.empty.label.clone()).boxed()) + .with_style(theme.empty.container) + .boxed(), + ) + .boxed(), ) - .with_max_width(500.0) + .with_style(theme.container) .boxed(), ) - .top() + .with_max_width(500.0) .named("go to line") } diff --git a/crates/gpui/src/app.rs b/crates/gpui/src/app.rs index 99c92b74128783c620deb10c22bb795b6fc8de7c..3aba2cbffba0c71c82aae899a66178748718c33e 100644 --- a/crates/gpui/src/app.rs +++ b/crates/gpui/src/app.rs @@ -4,7 +4,7 @@ use crate::{ elements::ElementBox, executor::{self, Task}, keymap::{self, Binding, Keystroke}, - platform::{self, CursorStyle, Platform, PromptLevel, WindowOptions}, + platform::{self, Platform, PromptLevel, WindowOptions}, presenter::Presenter, util::post_inc, AssetCache, AssetSource, ClipboardItem, FontCache, PathPromptOptions, TextLayoutCache, @@ -31,10 +31,7 @@ use std::{ path::{Path, PathBuf}, pin::Pin, rc::{self, Rc}, - sync::{ - atomic::{AtomicUsize, Ordering::SeqCst}, - Arc, Weak, - }, + sync::{Arc, Weak}, time::Duration, }; @@ -766,7 +763,6 @@ pub struct MutableAppContext { pending_global_notifications: HashSet, pending_flushes: usize, flushing_effects: bool, - next_cursor_style_handle_id: Arc, halt_action_dispatch: bool, } @@ -818,7 +814,6 @@ impl MutableAppContext { pending_global_notifications: HashSet::new(), pending_flushes: 0, flushing_effects: false, - next_cursor_style_handle_id: Default::default(), halt_action_dispatch: false, } } @@ -1596,6 +1591,7 @@ impl MutableAppContext { Window { root_view: root_view.clone().into(), focused_view_id: Some(root_view.id()), + is_active: true, invalidation: None, }, ); @@ -1643,10 +1639,17 @@ impl MutableAppContext { })); } + { + let mut app = self.upgrade(); + window.on_active_status_change(Box::new(move |is_active| { + app.update(|cx| cx.window_changed_active_status(window_id, is_active)) + })); + } + { let mut app = self.upgrade(); window.on_resize(Box::new(move || { - app.update(|cx| cx.resize_window(window_id)) + app.update(|cx| cx.window_was_resized(window_id)) })); } @@ -1861,6 +1864,10 @@ impl MutableAppContext { .get_or_insert(WindowInvalidation::default()); } } + Effect::ActivateWindow { + window_id, + is_active, + } => self.handle_activation_effect(window_id, is_active), Effect::RefreshWindows => { refreshing = true; } @@ -1919,11 +1926,18 @@ impl MutableAppContext { } } - fn resize_window(&mut self, window_id: usize) { + fn window_was_resized(&mut self, window_id: usize) { self.pending_effects .push_back(Effect::ResizeWindow { window_id }); } + fn window_changed_active_status(&mut self, window_id: usize, is_active: bool) { + self.pending_effects.push_back(Effect::ActivateWindow { + window_id, + is_active, + }); + } + pub fn refresh_windows(&mut self) { self.pending_effects.push_back(Effect::RefreshWindows); } @@ -1949,16 +1963,6 @@ impl MutableAppContext { self.presenters_and_platform_windows = presenters; } - pub fn set_cursor_style(&mut self, style: CursorStyle) -> CursorStyleHandle { - self.platform.set_cursor_style(style); - let id = self.next_cursor_style_handle_id.fetch_add(1, SeqCst); - CursorStyleHandle { - id, - next_cursor_style_handle_id: self.next_cursor_style_handle_id.clone(), - platform: self.platform(), - } - } - fn handle_subscription_effect( &mut self, entity_id: usize, @@ -2219,6 +2223,34 @@ impl MutableAppContext { } } + fn handle_activation_effect(&mut self, window_id: usize, active: bool) { + if self + .cx + .windows + .get(&window_id) + .map(|w| w.is_active) + .map_or(false, |cur_active| cur_active == active) + { + return; + } + + self.update(|this| { + let window = this.cx.windows.get_mut(&window_id)?; + window.is_active = active; + let view_id = window.focused_view_id?; + if let Some(mut view) = this.cx.views.remove(&(window_id, view_id)) { + if active { + view.on_focus(this, window_id, view_id); + } else { + view.on_blur(this, window_id, view_id); + } + this.cx.views.insert((window_id, view_id), view); + } + + Some(()) + }); + } + fn handle_focus_effect(&mut self, window_id: usize, focused_id: Option) { self.pending_focus_index.take(); @@ -2582,6 +2614,7 @@ impl ReadView for AppContext { struct Window { root_view: AnyViewHandle, focused_view_id: Option, + is_active: bool, invalidation: Option, } @@ -2648,6 +2681,10 @@ pub enum Effect { ResizeWindow { window_id: usize, }, + ActivateWindow { + window_id: usize, + is_active: bool, + }, RefreshWindows, } @@ -2729,6 +2766,14 @@ impl Debug for Effect { .debug_struct("Effect::RefreshWindow") .field("window_id", window_id) .finish(), + Effect::ActivateWindow { + window_id, + is_active, + } => f + .debug_struct("Effect::ActivateWindow") + .field("window_id", window_id) + .field("is_active", is_active) + .finish(), Effect::RefreshWindows => f.debug_struct("Effect::FullViewRefresh").finish(), } } @@ -4452,20 +4497,6 @@ impl Drop for ElementStateHandle { } } -pub struct CursorStyleHandle { - id: usize, - next_cursor_style_handle_id: Arc, - platform: Arc, -} - -impl Drop for CursorStyleHandle { - fn drop(&mut self) { - if self.id + 1 == self.next_cursor_style_handle_id.load(SeqCst) { - self.platform.set_cursor_style(CursorStyle::Arrow); - } - } -} - #[must_use] pub enum Subscription { Subscription { diff --git a/crates/gpui/src/elements/container.rs b/crates/gpui/src/elements/container.rs index 711ab1f6a6265c4b4b96310f1c812eb7e98661df..62f19636b7c5dd95a02d7a6f4d200b4343ddec9c 100644 --- a/crates/gpui/src/elements/container.rs +++ b/crates/gpui/src/elements/container.rs @@ -1,17 +1,17 @@ -use pathfinder_geometry::rect::RectF; -use serde::Deserialize; -use serde_json::json; - use crate::{ color::Color, geometry::{ deserialize_vec2f, + rect::RectF, vector::{vec2f, Vector2F}, }, json::ToJson, + platform::CursorStyle, scene::{self, Border, Quad}, Element, ElementBox, Event, EventContext, LayoutContext, PaintContext, SizeConstraint, }; +use serde::Deserialize; +use serde_json::json; #[derive(Clone, Copy, Debug, Default, Deserialize)] pub struct ContainerStyle { @@ -27,6 +27,8 @@ pub struct ContainerStyle { pub corner_radius: f32, #[serde(default)] pub shadow: Option, + #[serde(default)] + pub cursor: Option, } pub struct Container { @@ -128,6 +130,11 @@ impl Container { self } + pub fn with_cursor(mut self, style: CursorStyle) -> Self { + self.style.cursor = Some(style); + self + } + fn margin_size(&self) -> Vector2F { vec2f( self.style.margin.left + self.style.margin.right, @@ -205,6 +212,10 @@ impl Element for Container { }); } + if let Some(style) = self.style.cursor { + cx.scene.push_cursor_style(quad_bounds, style); + } + let child_origin = quad_bounds.origin() + vec2f(self.style.padding.left, self.style.padding.top); diff --git a/crates/gpui/src/elements/mouse_event_handler.rs b/crates/gpui/src/elements/mouse_event_handler.rs index 1d1e934d03be92d80ea48924372fc088198a2631..12166d45b541b3d9316c372a464b2e121775b4ca 100644 --- a/crates/gpui/src/elements/mouse_event_handler.rs +++ b/crates/gpui/src/elements/mouse_event_handler.rs @@ -5,8 +5,8 @@ use crate::{ vector::{vec2f, Vector2F}, }, platform::CursorStyle, - CursorStyleHandle, DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle, - Event, EventContext, LayoutContext, PaintContext, SizeConstraint, + DebugContext, Element, ElementBox, ElementStateContext, ElementStateHandle, Event, + EventContext, LayoutContext, PaintContext, SizeConstraint, }; use serde_json::json; @@ -25,7 +25,6 @@ pub struct MouseState { pub hovered: bool, pub clicked: bool, prev_drag_position: Option, - cursor_style_handle: Option, } impl MouseEventHandler { @@ -72,6 +71,14 @@ impl MouseEventHandler { self.padding = padding; self } + + fn hit_bounds(&self, bounds: RectF) -> RectF { + RectF::from_points( + bounds.origin() - vec2f(self.padding.left, self.padding.top), + bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom), + ) + .round_out() + } } impl Element for MouseEventHandler { @@ -93,6 +100,10 @@ impl Element for MouseEventHandler { _: &mut Self::LayoutState, cx: &mut PaintContext, ) -> Self::PaintState { + if let Some(cursor_style) = self.cursor_style { + cx.scene + .push_cursor_style(self.hit_bounds(bounds), cursor_style); + } self.child.paint(bounds.origin(), visible_bounds, cx); } @@ -105,19 +116,13 @@ impl Element for MouseEventHandler { _: &mut Self::PaintState, cx: &mut EventContext, ) -> bool { - let cursor_style = self.cursor_style; + let hit_bounds = self.hit_bounds(visible_bounds); let mouse_down_handler = self.mouse_down_handler.as_mut(); let click_handler = self.click_handler.as_mut(); let drag_handler = self.drag_handler.as_mut(); let handled_in_child = self.child.dispatch_event(event, cx); - let hit_bounds = RectF::from_points( - visible_bounds.origin() - vec2f(self.padding.left, self.padding.top), - visible_bounds.lower_right() + vec2f(self.padding.right, self.padding.bottom), - ) - .round_out(); - self.state.update(cx, |state, cx| match event { Event::MouseMoved { position, @@ -127,16 +132,6 @@ impl Element for MouseEventHandler { let mouse_in = hit_bounds.contains_point(*position); if state.hovered != mouse_in { state.hovered = mouse_in; - if let Some(cursor_style) = cursor_style { - if !state.clicked { - if state.hovered { - state.cursor_style_handle = - Some(cx.set_cursor_style(cursor_style)); - } else { - state.cursor_style_handle = None; - } - } - } cx.notify(); return true; } @@ -160,9 +155,6 @@ impl Element for MouseEventHandler { state.prev_drag_position = None; if !handled_in_child && state.clicked { state.clicked = false; - if !state.hovered { - state.cursor_style_handle = None; - } cx.notify(); if let Some(handler) = click_handler { if hit_bounds.contains_point(*position) { diff --git a/crates/gpui/src/platform.rs b/crates/gpui/src/platform.rs index 7e67d8b75292475606e41cb2b1f1c63ef8b22a3d..5e4e639bc87bc685ff07791290f03069494d92e7 100644 --- a/crates/gpui/src/platform.rs +++ b/crates/gpui/src/platform.rs @@ -21,6 +21,7 @@ use anyhow::{anyhow, Result}; use async_task::Runnable; pub use event::{Event, NavigationDirection}; use postage::oneshot; +use serde::Deserialize; use std::{ any::Any, path::{Path, PathBuf}, @@ -86,6 +87,7 @@ pub trait Dispatcher: Send + Sync { pub trait Window: WindowContext { fn as_any_mut(&mut self) -> &mut dyn Any; fn on_event(&mut self, callback: Box); + fn on_active_status_change(&mut self, callback: Box); fn on_resize(&mut self, callback: Box); fn on_close(&mut self, callback: Box); fn prompt(&self, level: PromptLevel, msg: &str, answers: &[&str]) -> oneshot::Receiver; @@ -125,11 +127,12 @@ pub enum PromptLevel { Critical, } -#[derive(Copy, Clone, Debug)] +#[derive(Copy, Clone, Debug, Deserialize)] pub enum CursorStyle { Arrow, ResizeLeftRight, PointingHand, + IBeam, } #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)] diff --git a/crates/gpui/src/platform/mac/platform.rs b/crates/gpui/src/platform/mac/platform.rs index 5554a96dbb209d23f14c68b0bfd5fb9626d3aa3d..fc1b7e59d80d3a9b721a67787bc4c140727fa10b 100644 --- a/crates/gpui/src/platform/mac/platform.rs +++ b/crates/gpui/src/platform/mac/platform.rs @@ -583,6 +583,7 @@ impl platform::Platform for MacPlatform { CursorStyle::Arrow => msg_send![class!(NSCursor), arrowCursor], CursorStyle::ResizeLeftRight => msg_send![class!(NSCursor), resizeLeftRightCursor], CursorStyle::PointingHand => msg_send![class!(NSCursor), pointingHandCursor], + CursorStyle::IBeam => msg_send![class!(NSCursor), IBeamCursor], }; let _: () = msg_send![cursor, set]; } diff --git a/crates/gpui/src/platform/mac/window.rs b/crates/gpui/src/platform/mac/window.rs index f6798e15af3c2d6688a5fb3bf6b529ed2122446a..518cefcd60aebde6329e5a3c8c184dc8ccd660ca 100644 --- a/crates/gpui/src/platform/mac/window.rs +++ b/crates/gpui/src/platform/mac/window.rs @@ -73,6 +73,14 @@ unsafe fn build_classes() { sel!(windowDidResize:), window_did_resize as extern "C" fn(&Object, Sel, id), ); + decl.add_method( + sel!(windowDidBecomeKey:), + window_did_change_key_status as extern "C" fn(&Object, Sel, id), + ); + decl.add_method( + sel!(windowDidResignKey:), + window_did_change_key_status as extern "C" fn(&Object, Sel, id), + ); decl.add_method(sel!(close), close_window as extern "C" fn(&Object, Sel)); decl.register() }; @@ -157,6 +165,7 @@ struct WindowState { id: usize, native_window: id, event_callback: Option>, + activate_callback: Option>, resize_callback: Option>, close_callback: Option>, synthetic_drag_counter: usize, @@ -234,6 +243,7 @@ impl Window { event_callback: None, resize_callback: None, close_callback: None, + activate_callback: None, synthetic_drag_counter: 0, executor, scene_to_render: Default::default(), @@ -333,6 +343,10 @@ impl platform::Window for Window { self.0.as_ref().borrow_mut().close_callback = Some(callback); } + fn on_active_status_change(&mut self, callback: Box) { + self.0.as_ref().borrow_mut().activate_callback = Some(callback); + } + fn prompt( &self, level: platform::PromptLevel, @@ -598,6 +612,29 @@ extern "C" fn window_did_resize(this: &Object, _: Sel, _: id) { window_state.as_ref().borrow().move_traffic_light(); } +extern "C" fn window_did_change_key_status(this: &Object, selector: Sel, _: id) { + let is_active = if selector == sel!(windowDidBecomeKey:) { + true + } else if selector == sel!(windowDidResignKey:) { + false + } else { + unreachable!(); + }; + + let window_state = unsafe { get_window_state(this) }; + let executor = window_state.as_ref().borrow().executor.clone(); + executor + .spawn(async move { + let mut window_state_borrow = window_state.as_ref().borrow_mut(); + if let Some(mut callback) = window_state_borrow.activate_callback.take() { + drop(window_state_borrow); + callback(is_active); + window_state.borrow_mut().activate_callback = Some(callback); + }; + }) + .detach(); +} + extern "C" fn close_window(this: &Object, _: Sel) { unsafe { let close_callback = { diff --git a/crates/gpui/src/platform/test.rs b/crates/gpui/src/platform/test.rs index 6804b39f7cea3147cf441a70f9a4807a25283303..8786eff25510bb3aeca85a7c2fb839f6803d4fc5 100644 --- a/crates/gpui/src/platform/test.rs +++ b/crates/gpui/src/platform/test.rs @@ -229,6 +229,8 @@ impl super::Window for Window { self.event_handlers.push(callback); } + fn on_active_status_change(&mut self, _: Box) {} + fn on_resize(&mut self, callback: Box) { self.resize_handlers.push(callback); } diff --git a/crates/gpui/src/presenter.rs b/crates/gpui/src/presenter.rs index 793f41f48782079cf8008cc896587cbb5a50a5bc..a7d715fadf2fb68b957702d052c54c25aec35980 100644 --- a/crates/gpui/src/presenter.rs +++ b/crates/gpui/src/presenter.rs @@ -4,7 +4,7 @@ use crate::{ font_cache::FontCache, geometry::rect::RectF, json::{self, ToJson}, - platform::Event, + platform::{CursorStyle, Event}, text_layout::TextLayoutCache, Action, AnyModelHandle, AnyViewHandle, AnyWeakModelHandle, AssetCache, ElementBox, ElementStateContext, Entity, FontSystem, ModelHandle, ReadModel, ReadView, Scene, @@ -22,6 +22,7 @@ pub struct Presenter { window_id: usize, pub(crate) rendered_views: HashMap, parents: HashMap, + cursor_styles: Vec<(RectF, CursorStyle)>, font_cache: Arc, text_layout_cache: TextLayoutCache, asset_cache: Arc, @@ -42,6 +43,7 @@ impl Presenter { window_id, rendered_views: cx.render_views(window_id, titlebar_height), parents: HashMap::new(), + cursor_styles: Default::default(), font_cache, text_layout_cache, asset_cache, @@ -118,6 +120,7 @@ impl Presenter { RectF::new(Vector2F::zero(), window_size), ); self.text_layout_cache.finish_frame(); + self.cursor_styles = scene.cursor_styles(); if let Some(event) = self.last_mouse_moved_event.clone() { self.dispatch_event(event, cx) @@ -171,8 +174,22 @@ impl Presenter { pub fn dispatch_event(&mut self, event: Event, cx: &mut MutableAppContext) { if let Some(root_view_id) = cx.root_view_id(self.window_id) { match event { - Event::MouseMoved { .. } => { + Event::MouseMoved { + position, + left_mouse_down, + } => { self.last_mouse_moved_event = Some(event.clone()); + + if !left_mouse_down { + let mut style_to_assign = CursorStyle::Arrow; + for (bounds, style) in self.cursor_styles.iter().rev() { + if bounds.contains_point(position) { + style_to_assign = *style; + break; + } + } + cx.platform().set_cursor_style(style_to_assign); + } } Event::LeftMouseDragged { position } => { self.last_mouse_moved_event = Some(Event::MouseMoved { diff --git a/crates/gpui/src/scene.rs b/crates/gpui/src/scene.rs index 6c23a731bcfe7bc13cc2421cc856cdf28df93eba..7c358b85a04991272b05a4fb4ececeec07b51ef0 100644 --- a/crates/gpui/src/scene.rs +++ b/crates/gpui/src/scene.rs @@ -7,6 +7,7 @@ use crate::{ fonts::{FontId, GlyphId}, geometry::{rect::RectF, vector::Vector2F}, json::ToJson, + platform::CursorStyle, ImageData, }; @@ -32,6 +33,7 @@ pub struct Layer { image_glyphs: Vec, icons: Vec, paths: Vec, + cursor_styles: Vec<(RectF, CursorStyle)>, } #[derive(Default, Debug)] @@ -173,6 +175,13 @@ impl Scene { self.stacking_contexts.iter().flat_map(|s| &s.layers) } + pub fn cursor_styles(&self) -> Vec<(RectF, CursorStyle)> { + self.layers() + .flat_map(|layer| &layer.cursor_styles) + .copied() + .collect() + } + pub fn push_stacking_context(&mut self, clip_bounds: Option) { self.active_stacking_context_stack .push(self.stacking_contexts.len()); @@ -197,6 +206,10 @@ impl Scene { self.active_layer().push_quad(quad) } + pub fn push_cursor_style(&mut self, bounds: RectF, style: CursorStyle) { + self.active_layer().push_cursor_style(bounds, style); + } + pub fn push_image(&mut self, image: Image) { self.active_layer().push_image(image) } @@ -285,6 +298,7 @@ impl Layer { glyphs: Default::default(), icons: Default::default(), paths: Default::default(), + cursor_styles: Default::default(), } } @@ -302,6 +316,14 @@ impl Layer { self.quads.as_slice() } + fn push_cursor_style(&mut self, bounds: RectF, style: CursorStyle) { + if let Some(bounds) = bounds.intersection(self.clip_bounds.unwrap_or(bounds)) { + if can_draw(bounds) { + self.cursor_styles.push((bounds, style)); + } + } + } + fn push_underline(&mut self, underline: Underline) { if underline.width > 0. { self.underlines.push(underline); diff --git a/crates/language/Cargo.toml b/crates/language/Cargo.toml index 275581f807dafa30f8a95421fc7d8990aff3511c..ab648664199c4b93b16022645600be4848145fd0 100644 --- a/crates/language/Cargo.toml +++ b/crates/language/Cargo.toml @@ -15,6 +15,7 @@ test-support = [ "lsp/test-support", "text/test-support", "tree-sitter-rust", + "tree-sitter-typescript", "util/test-support", ] @@ -45,7 +46,8 @@ similar = "1.3" smallvec = { version = "1.6", features = ["union"] } smol = "1.2" tree-sitter = "0.20" -tree-sitter-rust = { version = "0.20.0", optional = true } +tree-sitter-rust = { version = "*", optional = true } +tree-sitter-typescript = { version = "*", optional = true } [dev-dependencies] client = { path = "../client", features = ["test-support"] } @@ -57,6 +59,6 @@ util = { path = "../util", features = ["test-support"] } ctor = "0.1" env_logger = "0.8" rand = "0.8.3" -tree-sitter-json = "0.19.0" -tree-sitter-rust = "0.20.0" +tree-sitter-json = "*" +tree-sitter-rust = "*" unindent = "0.1.7" diff --git a/crates/language/src/buffer.rs b/crates/language/src/buffer.rs index 95aa27b6d27999bbec09b86151a0cf6dfe046995..3a1c0f066769ceb3898f2f69393a88710a5629e3 100644 --- a/crates/language/src/buffer.rs +++ b/crates/language/src/buffer.rs @@ -38,7 +38,7 @@ use tree_sitter::{InputEdit, QueryCursor, Tree}; use util::TryFutureExt as _; #[cfg(any(test, feature = "test-support"))] -pub use tree_sitter_rust; +pub use {tree_sitter_rust, tree_sitter_typescript}; pub use lsp::DiagnosticSeverity; @@ -1638,6 +1638,34 @@ impl BufferSnapshot { .and_then(|language| language.grammar.as_ref()) } + pub fn range_for_word_token_at( + &self, + position: T, + ) -> Option> { + let offset = position.to_offset(self); + + // Find the first leaf node that touches the position. + let tree = self.tree.as_ref()?; + let mut cursor = tree.root_node().walk(); + while cursor.goto_first_child_for_byte(offset).is_some() {} + let node = cursor.node(); + if node.child_count() > 0 { + return None; + } + + // Check that the leaf node contains word characters. + let range = node.byte_range(); + if self + .text_for_range(range.clone()) + .flat_map(str::chars) + .any(|c| c.is_alphanumeric()) + { + return Some(range); + } else { + None + } + } + pub fn range_for_syntax_ancestor(&self, range: Range) -> Option> { let tree = self.tree.as_ref()?; let range = range.start.to_offset(self)..range.end.to_offset(self); @@ -1730,7 +1758,7 @@ impl BufferSnapshot { .and_then(|language| language.grammar.as_ref())?; let mut cursor = QueryCursorHandle::new(); - cursor.set_byte_range(range); + cursor.set_byte_range(range.clone()); let matches = cursor.matches( &grammar.outline_query, tree.root_node(), @@ -1750,7 +1778,10 @@ impl BufferSnapshot { let items = matches .filter_map(|mat| { let item_node = mat.nodes_for_capture_index(item_capture_ix).next()?; - let range = item_node.start_byte()..item_node.end_byte(); + let item_range = item_node.start_byte()..item_node.end_byte(); + if item_range.end < range.start || item_range.start > range.end { + return None; + } let mut text = String::new(); let mut name_ranges = Vec::new(); let mut highlight_ranges = Vec::new(); @@ -1808,15 +1839,15 @@ impl BufferSnapshot { } while stack.last().map_or(false, |prev_range| { - !prev_range.contains(&range.start) || !prev_range.contains(&range.end) + !prev_range.contains(&item_range.start) || !prev_range.contains(&item_range.end) }) { stack.pop(); } - stack.push(range.clone()); + stack.push(item_range.clone()); Some(OutlineItem { depth: stack.len() - 1, - range: self.anchor_after(range.start)..self.anchor_before(range.end), + range: self.anchor_after(item_range.start)..self.anchor_before(item_range.end), text, highlight_ranges, name_ranges, diff --git a/crates/language/src/highlight_map.rs b/crates/language/src/highlight_map.rs index 74734fbc5b376255eff644cd1930c5cf1780f761..36ed286beaac48e23e15950d575136b074171bc5 100644 --- a/crates/language/src/highlight_map.rs +++ b/crates/language/src/highlight_map.rs @@ -51,6 +51,10 @@ impl HighlightMap { } impl HighlightId { + pub fn is_default(&self) -> bool { + *self == DEFAULT_SYNTAX_HIGHLIGHT_ID + } + pub fn style(&self, theme: &SyntaxTheme) -> Option { theme .highlights diff --git a/crates/language/src/language.rs b/crates/language/src/language.rs index 8b7f751593b9c8fe77f155f24c4d6d78802ea845..14b5a288e1e08f2f9f333b3782bdf1c4b975da42 100644 --- a/crates/language/src/language.rs +++ b/crates/language/src/language.rs @@ -546,7 +546,9 @@ impl Language { { let end_offset = offset + chunk.text.len(); if let Some(highlight_id) = chunk.syntax_highlight_id { - result.push((offset..end_offset, highlight_id)); + if !highlight_id.is_default() { + result.push((offset..end_offset, highlight_id)); + } } offset = end_offset; } diff --git a/crates/picker/src/picker.rs b/crates/picker/src/picker.rs index 4e4a7e92aad96fb9de331d975488617cf1ec3047..0c90268dadf2deb0fd5d2c5c29e815920cf22690 100644 --- a/crates/picker/src/picker.rs +++ b/crates/picker/src/picker.rs @@ -99,8 +99,6 @@ impl View for Picker { .constrained() .with_max_width(self.max_size.x()) .with_max_height(self.max_size.y()) - .aligned() - .top() .named("picker") } diff --git a/crates/project/src/project.rs b/crates/project/src/project.rs index c2e444741e37ef434c3c23f15857c32d44517af5..5243afe91c686f428a87b814e8d4886c1eb62c45 100644 --- a/crates/project/src/project.rs +++ b/crates/project/src/project.rs @@ -669,6 +669,10 @@ impl Project { .map(|worktree| worktree.read(cx).id()) } + pub fn can_share(&self, cx: &AppContext) -> bool { + self.is_local() && self.visible_worktrees(cx).next().is_some() + } + pub fn share(&self, cx: &mut ModelContext) -> Task> { let rpc = self.client.clone(); cx.spawn(|this, mut cx| async move { @@ -2488,26 +2492,51 @@ impl Project { }; source_buffer_handle.read_with(&cx, |this, _| { + let snapshot = this.snapshot(); + let clipped_position = this.clip_point_utf16(position, Bias::Left); + let mut range_for_token = None; Ok(completions .into_iter() .filter_map(|lsp_completion| { let (old_range, new_text) = match lsp_completion.text_edit.as_ref() { + // If the language server provides a range to overwrite, then + // check that the range is valid. Some(lsp::CompletionTextEdit::Edit(edit)) => { - (range_from_lsp(edit.range), edit.new_text.clone()) + let range = range_from_lsp(edit.range); + let start = snapshot.clip_point_utf16(range.start, Bias::Left); + let end = snapshot.clip_point_utf16(range.end, Bias::Left); + if start != range.start || end != range.end { + log::info!("completion out of expected range"); + return None; + } + ( + snapshot.anchor_before(start)..snapshot.anchor_after(end), + edit.new_text.clone(), + ) } + // If the language server does not provide a range, then infer + // the range based on the syntax tree. None => { - let clipped_position = - this.clip_point_utf16(position, Bias::Left); if position != clipped_position { log::info!("completion out of expected range"); return None; } + let Range { start, end } = range_for_token + .get_or_insert_with(|| { + let offset = position.to_offset(&snapshot); + snapshot + .range_for_word_token_at(offset) + .unwrap_or_else(|| offset..offset) + }) + .clone(); + let text = lsp_completion + .insert_text + .as_ref() + .unwrap_or(&lsp_completion.label) + .clone(); ( - this.common_prefix_at( - clipped_position, - &lsp_completion.label, - ), - lsp_completion.label.clone(), + snapshot.anchor_before(start)..snapshot.anchor_after(end), + text.clone(), ) } Some(lsp::CompletionTextEdit::InsertAndReplace(_)) => { @@ -2516,28 +2545,20 @@ impl Project { } }; - let clipped_start = this.clip_point_utf16(old_range.start, Bias::Left); - let clipped_end = this.clip_point_utf16(old_range.end, Bias::Left); - if clipped_start == old_range.start && clipped_end == old_range.end { - Some(Completion { - old_range: this.anchor_before(old_range.start) - ..this.anchor_after(old_range.end), - new_text, - label: language - .as_ref() - .and_then(|l| l.label_for_completion(&lsp_completion)) - .unwrap_or_else(|| { - CodeLabel::plain( - lsp_completion.label.clone(), - lsp_completion.filter_text.as_deref(), - ) - }), - lsp_completion, - }) - } else { - log::info!("completion out of expected range"); - None - } + Some(Completion { + old_range, + new_text, + label: language + .as_ref() + .and_then(|l| l.label_for_completion(&lsp_completion)) + .unwrap_or_else(|| { + CodeLabel::plain( + lsp_completion.label.clone(), + lsp_completion.filter_text.as_deref(), + ) + }), + lsp_completion, + }) }) .collect()) }) @@ -4889,8 +4910,8 @@ mod tests { use futures::{future, StreamExt}; use gpui::test::subscribe; use language::{ - tree_sitter_rust, Diagnostic, FakeLspAdapter, LanguageConfig, OffsetRangeExt, Point, - ToPoint, + tree_sitter_rust, tree_sitter_typescript, Diagnostic, FakeLspAdapter, LanguageConfig, + OffsetRangeExt, Point, ToPoint, }; use lsp::Url; use serde_json::json; @@ -6507,6 +6528,75 @@ mod tests { } } + #[gpui::test] + async fn test_completions_without_edit_ranges(cx: &mut gpui::TestAppContext) { + let mut language = Language::new( + LanguageConfig { + name: "TypeScript".into(), + path_suffixes: vec!["ts".to_string()], + ..Default::default() + }, + Some(tree_sitter_typescript::language_typescript()), + ); + let mut fake_language_servers = language.set_fake_lsp_adapter(Default::default()); + + let fs = FakeFs::new(cx.background()); + fs.insert_tree( + "/dir", + json!({ + "a.ts": "", + }), + ) + .await; + + let project = Project::test(fs, cx); + project.update(cx, |project, _| project.languages.add(Arc::new(language))); + + let (tree, _) = project + .update(cx, |project, cx| { + project.find_or_create_local_worktree("/dir", true, cx) + }) + .await + .unwrap(); + let worktree_id = tree.read_with(cx, |tree, _| tree.id()); + cx.read(|cx| tree.read(cx).as_local().unwrap().scan_complete()) + .await; + + let buffer = project + .update(cx, |p, cx| p.open_buffer((worktree_id, "a.ts"), cx)) + .await + .unwrap(); + + let fake_server = fake_language_servers.next().await.unwrap(); + + let text = "let a = b.fqn"; + buffer.update(cx, |buffer, cx| buffer.set_text(text, cx)); + let completions = project.update(cx, |project, cx| { + project.completions(&buffer, text.len(), cx) + }); + + fake_server + .handle_request::(|_, _| async move { + Ok(Some(lsp::CompletionResponse::Array(vec![ + lsp::CompletionItem { + label: "fullyQualifiedName?".into(), + insert_text: Some("fullyQualifiedName".into()), + ..Default::default() + }, + ]))) + }) + .next() + .await; + let completions = completions.await.unwrap(); + let snapshot = buffer.read_with(cx, |buffer, _| buffer.snapshot()); + assert_eq!(completions.len(), 1); + assert_eq!(completions[0].new_text, "fullyQualifiedName"); + assert_eq!( + completions[0].old_range.to_offset(&snapshot), + text.len() - 3..text.len() + ); + } + #[gpui::test(iterations = 10)] async fn test_apply_code_actions_with_commands(cx: &mut gpui::TestAppContext) { let mut language = Language::new( diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs index dd6a7a79c71326e3a3772d331bdc95394145ea72..b4533298ac1ca732f90dbde1e74556ded3c8bd17 100644 --- a/crates/theme/src/theme.rs +++ b/crates/theme/src/theme.rs @@ -43,6 +43,7 @@ pub struct Workspace { pub status_bar: StatusBar, pub toolbar: Toolbar, pub disconnected_overlay: ContainedText, + pub modal: ContainerStyle, } #[derive(Clone, Deserialize, Default)] @@ -54,8 +55,10 @@ pub struct Titlebar { pub avatar_width: f32, pub avatar_ribbon: AvatarRibbon, pub offline_icon: OfflineIcon, - pub share_icon_color: Color, - pub share_icon_active_color: Color, + pub share_icon: ShareIcon, + pub hovered_share_icon: ShareIcon, + pub active_share_icon: ShareIcon, + pub hovered_active_share_icon: ShareIcon, pub avatar: ImageStyle, pub sign_in_prompt: ContainedText, pub hovered_sign_in_prompt: ContainedText, @@ -78,6 +81,13 @@ pub struct OfflineIcon { pub color: Color, } +#[derive(Clone, Deserialize, Default)] +pub struct ShareIcon { + #[serde(flatten)] + pub container: ContainerStyle, + pub color: Color, +} + #[derive(Clone, Deserialize, Default)] pub struct Tab { pub height: f32, diff --git a/crates/theme_selector/src/theme_selector.rs b/crates/theme_selector/src/theme_selector.rs index f1e933774f8e0dfab2ff6b65b30fb5bb465432c7..5c679be841b88d7508b28d5bf819f1b6c6710cee 100644 --- a/crates/theme_selector/src/theme_selector.rs +++ b/crates/theme_selector/src/theme_selector.rs @@ -36,7 +36,12 @@ impl ThemeSelector { let handle = cx.weak_handle(); let picker = cx.add_view(|cx| Picker::new(handle, cx)); let original_theme = cx.global::().theme.clone(); - let theme_names = registry.list().collect::>(); + let mut theme_names = registry.list().collect::>(); + theme_names.sort_unstable_by(|a, b| { + a.ends_with("dark") + .cmp(&b.ends_with("dark")) + .then_with(|| a.cmp(&b)) + }); let matches = theme_names .iter() .map(|name| StringMatch { diff --git a/crates/vim/src/insert.rs b/crates/vim/src/insert.rs index c98c9db8411e13a2d3c57a196dc9bc17d89f6135..afaeda17b05f083905e7d81e1b390e69c9ce8000 100644 --- a/crates/vim/src/insert.rs +++ b/crates/vim/src/insert.rs @@ -28,7 +28,7 @@ mod test { #[gpui::test] async fn test_enter_and_exit_insert_mode(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "").await; + let mut cx = VimTestContext::new(cx, true).await; cx.simulate_keystroke("i"); assert_eq!(cx.mode(), Mode::Insert); cx.simulate_keystrokes(["T", "e", "s", "t"]); diff --git a/crates/vim/src/motion.rs b/crates/vim/src/motion.rs index 530ee1d657c2e26fe47b09882f45ae45224de569..95286516ba21756c9cabe43a43964e97f69ba4ae 100644 --- a/crates/vim/src/motion.rs +++ b/crates/vim/src/motion.rs @@ -4,7 +4,7 @@ use editor::{ movement, Bias, DisplayPoint, }; use gpui::{actions, impl_actions, MutableAppContext}; -use language::SelectionGoal; +use language::{Selection, SelectionGoal}; use serde::Deserialize; use workspace::Workspace; @@ -14,22 +14,15 @@ use crate::{ Vim, }; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum Motion { Left, Down, Up, Right, - NextWordStart { - ignore_punctuation: bool, - stop_at_newline: bool, - }, - NextWordEnd { - ignore_punctuation: bool, - }, - PreviousWordStart { - ignore_punctuation: bool, - }, + NextWordStart { ignore_punctuation: bool }, + NextWordEnd { ignore_punctuation: bool }, + PreviousWordStart { ignore_punctuation: bool }, StartOfLine, EndOfLine, StartOfDocument, @@ -41,8 +34,6 @@ pub enum Motion { struct NextWordStart { #[serde(default)] ignore_punctuation: bool, - #[serde(default)] - stop_at_newline: bool, } #[derive(Clone, Deserialize)] @@ -87,19 +78,8 @@ pub fn init(cx: &mut MutableAppContext) { cx.add_action(|_: &mut Workspace, _: &EndOfDocument, cx: _| motion(Motion::EndOfDocument, cx)); cx.add_action( - |_: &mut Workspace, - &NextWordStart { - ignore_punctuation, - stop_at_newline, - }: &NextWordStart, - cx: _| { - motion( - Motion::NextWordStart { - ignore_punctuation, - stop_at_newline, - }, - cx, - ) + |_: &mut Workspace, &NextWordStart { ignore_punctuation }: &NextWordStart, cx: _| { + motion(Motion::NextWordStart { ignore_punctuation }, cx) }, ); cx.add_action( @@ -128,29 +108,48 @@ fn motion(motion: Motion, cx: &mut MutableAppContext) { } } +// Motion handling is specified here: +// https://github.com/vim/vim/blob/master/runtime/doc/motion.txt impl Motion { + pub fn linewise(self) -> bool { + use Motion::*; + match self { + Down | Up | StartOfDocument | EndOfDocument => true, + _ => false, + } + } + + pub fn inclusive(self) -> bool { + use Motion::*; + if self.linewise() { + return true; + } + + match self { + EndOfLine | NextWordEnd { .. } => true, + Left | Right | StartOfLine | NextWordStart { .. } | PreviousWordStart { .. } => false, + _ => panic!("Exclusivity not defined for {self:?}"), + } + } + pub fn move_point( self, map: &DisplaySnapshot, point: DisplayPoint, goal: SelectionGoal, - block_cursor_positioning: bool, ) -> (DisplayPoint, SelectionGoal) { use Motion::*; match self { Left => (left(map, point), SelectionGoal::None), - Down => movement::down(map, point, goal), - Up => movement::up(map, point, goal), + Down => movement::down(map, point, goal, true), + Up => movement::up(map, point, goal, true), Right => (right(map, point), SelectionGoal::None), - NextWordStart { - ignore_punctuation, - stop_at_newline, - } => ( - next_word_start(map, point, ignore_punctuation, stop_at_newline), + NextWordStart { ignore_punctuation } => ( + next_word_start(map, point, ignore_punctuation), SelectionGoal::None, ), NextWordEnd { ignore_punctuation } => ( - next_word_end(map, point, ignore_punctuation, block_cursor_positioning), + next_word_end(map, point, ignore_punctuation), SelectionGoal::None, ), PreviousWordStart { ignore_punctuation } => ( @@ -164,11 +163,55 @@ impl Motion { } } - pub fn line_wise(self) -> bool { - use Motion::*; - match self { - Down | Up | StartOfDocument | EndOfDocument => true, - _ => false, + // Expands a selection using self motion for an operator + pub fn expand_selection( + self, + map: &DisplaySnapshot, + selection: &mut Selection, + expand_to_surrounding_newline: bool, + ) { + let (head, goal) = self.move_point(map, selection.head(), selection.goal); + selection.set_head(head, goal); + + if self.linewise() { + selection.start = map.prev_line_boundary(selection.start.to_point(map)).1; + + if expand_to_surrounding_newline { + if selection.end.row() < map.max_point().row() { + *selection.end.row_mut() += 1; + *selection.end.column_mut() = 0; + // Don't reset the end here + return; + } else if selection.start.row() > 0 { + *selection.start.row_mut() -= 1; + *selection.start.column_mut() = map.line_len(selection.start.row()); + } + } + + selection.end = map.next_line_boundary(selection.end.to_point(map)).1; + } else { + // If the motion is exclusive and the end of the motion is in column 1, the + // end of the motion is moved to the end of the previous line and the motion + // becomes inclusive. Example: "}" moves to the first line after a paragraph, + // but "d}" will not include that line. + let mut inclusive = self.inclusive(); + if !inclusive + && selection.end.row() > selection.start.row() + && selection.end.column() == 0 + && selection.end.row() > 0 + { + inclusive = true; + *selection.end.row_mut() -= 1; + *selection.end.column_mut() = 0; + selection.end = map.clip_point( + map.next_line_boundary(selection.end.to_point(map)).1, + Bias::Left, + ); + } + + if inclusive && selection.end.column() < map.line_len(selection.end.row()) { + *selection.end.column_mut() += 1; + } } } } @@ -187,7 +230,6 @@ fn next_word_start( map: &DisplaySnapshot, point: DisplayPoint, ignore_punctuation: bool, - stop_at_newline: bool, ) -> DisplayPoint { let mut crossed_newline = false; movement::find_boundary(map, point, |left, right| { @@ -196,8 +238,8 @@ fn next_word_start( let at_newline = right == '\n'; let found = (left_kind != right_kind && !right.is_whitespace()) - || (at_newline && (crossed_newline || stop_at_newline)) - || (at_newline && left == '\n'); // Prevents skipping repeated empty lines + || at_newline && crossed_newline + || at_newline && left == '\n'; // Prevents skipping repeated empty lines if at_newline { crossed_newline = true; @@ -210,7 +252,6 @@ fn next_word_end( map: &DisplaySnapshot, mut point: DisplayPoint, ignore_punctuation: bool, - before_end_character: bool, ) -> DisplayPoint { *point.column_mut() += 1; point = movement::find_boundary(map, point, |left, right| { @@ -221,13 +262,12 @@ fn next_word_end( }); // find_boundary clips, so if the character after the next character is a newline or at the end of the document, we know // we have backtraced already - if before_end_character - && !map - .chars_at(point) - .skip(1) - .next() - .map(|c| c == '\n') - .unwrap_or(true) + if !map + .chars_at(point) + .skip(1) + .next() + .map(|c| c == '\n') + .unwrap_or(true) { *point.column_mut() = point.column().saturating_sub(1); } diff --git a/crates/vim/src/normal.rs b/crates/vim/src/normal.rs index d0ca7ae870988887de804899004060c326aa1315..dc919b651c463862e106130f42199dca30cd151c 100644 --- a/crates/vim/src/normal.rs +++ b/crates/vim/src/normal.rs @@ -1,11 +1,17 @@ -use crate::{ - motion::Motion, - state::{Mode, Operator}, - Vim, -}; -use editor::Bias; -use gpui::MutableAppContext; -use language::SelectionGoal; +mod change; +mod delete; + +use crate::{motion::Motion, state::Operator, Vim}; +use change::init as change_init; +use gpui::{actions, MutableAppContext}; + +use self::{change::change_over, delete::delete_over}; + +actions!(vim, [InsertLineAbove, InsertLineBelow, InsertAfter]); + +pub fn init(cx: &mut MutableAppContext) { + change_init(cx); +} pub fn normal_motion(motion: Motion, cx: &mut MutableAppContext) { Vim::update(cx, |vim, cx| { @@ -23,82 +29,7 @@ pub fn normal_motion(motion: Motion, cx: &mut MutableAppContext) { fn move_cursor(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { vim.update_active_editor(cx, |editor, cx| { - editor.move_cursors(cx, |map, cursor, goal| { - motion.move_point(map, cursor, goal, true) - }) - }); -} - -fn change_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { - vim.update_active_editor(cx, |editor, cx| { - editor.transact(cx, |editor, cx| { - // Don't clip at line ends during change operation - editor.set_clip_at_line_ends(false, cx); - editor.move_selections(cx, |map, selection| { - let (head, goal) = motion.move_point(map, selection.head(), selection.goal, false); - selection.set_head(head, goal); - - if motion.line_wise() { - selection.start = map.prev_line_boundary(selection.start.to_point(map)).1; - selection.end = map.next_line_boundary(selection.end.to_point(map)).1; - } - }); - editor.set_clip_at_line_ends(true, cx); - editor.insert(&"", cx); - }); - }); - vim.switch_mode(Mode::Insert, cx) -} - -fn delete_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { - vim.update_active_editor(cx, |editor, cx| { - editor.transact(cx, |editor, cx| { - // Use goal column to preserve previous position - editor.set_clip_at_line_ends(false, cx); - editor.move_selections(cx, |map, selection| { - let original_head = selection.head(); - let (head, _) = motion.move_point(map, selection.head(), selection.goal, false); - // Set the goal column to the original position in order to fix it up - // after the deletion - selection.set_head(head, SelectionGoal::Column(original_head.column())); - - if motion.line_wise() { - if selection.end.row() == map.max_point().row() { - // Delete previous line break since we are at the end of the document - if selection.start.row() > 0 { - *selection.start.row_mut() = selection.start.row().saturating_sub(1); - selection.start = map.clip_point(selection.start, Bias::Left); - selection.start = - map.next_line_boundary(selection.start.to_point(map)).1; - } else { - // Selection covers the whole document. Just delete to the start of the - // line. - selection.start = - map.prev_line_boundary(selection.start.to_point(map)).1; - } - selection.end = map.next_line_boundary(selection.end.to_point(map)).1; - } else { - // Delete next line break so that we leave the previous line alone - selection.start = map.prev_line_boundary(selection.start.to_point(map)).1; - *selection.end.column_mut() = 0; - *selection.end.row_mut() += 1; - selection.end = map.clip_point(selection.end, Bias::Left); - } - } - }); - editor.insert(&"", cx); - - // Fixup cursor position after the deletion - editor.set_clip_at_line_ends(true, cx); - editor.move_cursors(cx, |map, mut cursor, goal| { - if motion.line_wise() { - if let SelectionGoal::Column(column) = goal { - *cursor.column_mut() = column - } - } - (map.clip_point(cursor, Bias::Left), SelectionGoal::None) - }); - }); + editor.move_cursors(cx, |map, cursor, goal| motion.move_point(map, cursor, goal)) }); } @@ -116,144 +47,218 @@ mod test { }; #[gpui::test] - async fn test_hjkl(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "Test\nTestTest\nTest").await; - cx.simulate_keystroke("l"); - cx.assert_editor_state(indoc! {" - T|est - TestTest - Test"}); - cx.simulate_keystroke("h"); - cx.assert_editor_state(indoc! {" - |Test - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_editor_state(indoc! {" - Test - |TestTest - Test"}); - cx.simulate_keystroke("k"); - cx.assert_editor_state(indoc! {" - |Test - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_editor_state(indoc! {" - Test - |TestTest - Test"}); + async fn test_h(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["h"]); + cx.assert("The q|uick", "The |quick"); + cx.assert("|The quick", "|The quick"); + cx.assert( + indoc! {" + The quick + |brown"}, + indoc! {" + The quick + |brown"}, + ); + } - // When moving left, cursor does not wrap to the previous line - cx.simulate_keystroke("h"); - cx.assert_editor_state(indoc! {" - Test - |TestTest - Test"}); + #[gpui::test] + async fn test_l(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["l"]); + cx.assert("The q|uick", "The qu|ick"); + cx.assert("The quic|k", "The quic|k"); + cx.assert( + indoc! {" + The quic|k + brown"}, + indoc! {" + The quic|k + brown"}, + ); + } - // When moving right, cursor does not reach the line end or wrap to the next line - for _ in 0..9 { - cx.simulate_keystroke("l"); - } - cx.assert_editor_state(indoc! {" - Test - TestTes|t - Test"}); + #[gpui::test] + async fn test_j(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["j"]); + cx.assert( + indoc! {" + The |quick + brown fox"}, + indoc! {" + The quick + brow|n fox"}, + ); + cx.assert( + indoc! {" + The quick + brow|n fox"}, + indoc! {" + The quick + brow|n fox"}, + ); + cx.assert( + indoc! {" + The quic|k + brown"}, + indoc! {" + The quick + brow|n"}, + ); + cx.assert( + indoc! {" + The quick + |brown"}, + indoc! {" + The quick + |brown"}, + ); + } - // Goal column respects the inability to reach the end of the line - cx.simulate_keystroke("k"); - cx.assert_editor_state(indoc! {" - Tes|t - TestTest - Test"}); - cx.simulate_keystroke("j"); - cx.assert_editor_state(indoc! {" - Test - TestTes|t - Test"}); + #[gpui::test] + async fn test_k(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["k"]); + cx.assert( + indoc! {" + The |quick + brown fox"}, + indoc! {" + The |quick + brown fox"}, + ); + cx.assert( + indoc! {" + The quick + brow|n fox"}, + indoc! {" + The |quick + brown fox"}, + ); + cx.assert( + indoc! {" + The + quic|k"}, + indoc! {" + Th|e + quick"}, + ); } #[gpui::test] async fn test_jump_to_line_boundaries(cx: &mut gpui::TestAppContext) { - let initial_content = indoc! {" - Test Test - - T"}; - let mut cx = VimTestContext::new(cx, true, initial_content).await; - - cx.simulate_keystroke("shift-$"); - cx.assert_editor_state(indoc! {" - Test Tes|t - - T"}); - cx.simulate_keystroke("0"); - cx.assert_editor_state(indoc! {" - |Test Test - - T"}); - - cx.simulate_keystroke("j"); - cx.simulate_keystroke("shift-$"); - cx.assert_editor_state(indoc! {" - Test Test - | - T"}); - cx.simulate_keystroke("0"); - cx.assert_editor_state(indoc! {" - Test Test - | - T"}); + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["shift-$"]); + cx.assert("T|est test", "Test tes|t"); + cx.assert("Test tes|t", "Test tes|t"); + cx.assert( + indoc! {" + The |quick + brown"}, + indoc! {" + The quic|k + brown"}, + ); + cx.assert( + indoc! {" + The quic|k + brown"}, + indoc! {" + The quic|k + brown"}, + ); - cx.simulate_keystroke("j"); - cx.simulate_keystroke("shift-$"); - cx.assert_editor_state(indoc! {" - Test Test - - |T"}); - cx.simulate_keystroke("0"); - cx.assert_editor_state(indoc! {" - Test Test - - |T"}); + let mut cx = cx.binding(["0"]); + cx.assert("Test |test", "|Test test"); + cx.assert("|Test test", "|Test test"); + cx.assert( + indoc! {" + The |quick + brown"}, + indoc! {" + |The quick + brown"}, + ); + cx.assert( + indoc! {" + |The quick + brown"}, + indoc! {" + |The quick + brown"}, + ); } #[gpui::test] async fn test_jump_to_end(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "").await; + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["shift-G"]); - cx.set_state( + cx.assert( indoc! {" - The |quick - - brown fox jumps - over the lazy dog"}, - Mode::Normal, + The |quick + + brown fox jumps + over the lazy dog"}, + indoc! {" + The quick + + brown fox jumps + over| the lazy dog"}, ); - cx.simulate_keystroke("shift-G"); - cx.assert_editor_state(indoc! {" + cx.assert( + indoc! {" + The quick + + brown fox jumps + over| the lazy dog"}, + indoc! {" + The quick + + brown fox jumps + over| the lazy dog"}, + ); + cx.assert( + indoc! {" + The qui|ck + + brown"}, + indoc! {" The quick - brown fox jumps - over| the lazy dog"}); - - // Repeat the action doesn't move - cx.simulate_keystroke("shift-G"); - cx.assert_editor_state(indoc! {" + brow|n"}, + ); + cx.assert( + indoc! {" + The qui|ck + + "}, + indoc! {" The quick - brown fox jumps - over| the lazy dog"}); + |"}, + ); } #[gpui::test] async fn test_next_word_start(cx: &mut gpui::TestAppContext) { - let (initial_content, cursor_offsets) = marked_text(indoc! {" + let mut cx = VimTestContext::new(cx, true).await; + let (_, cursor_offsets) = marked_text(indoc! {" The |quick|-|brown | | |fox_jumps |over |th||e"}); - let mut cx = VimTestContext::new(cx, true, &initial_content).await; + cx.set_state( + indoc! {" + |The quick-brown + + + fox_jumps over + the"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets { cx.simulate_keystroke("w"); @@ -261,13 +266,21 @@ mod test { } // Reset and test ignoring punctuation - cx.simulate_keystrokes(["g", "g", "0"]); let (_, cursor_offsets) = marked_text(indoc! {" The |quick-brown | | |fox_jumps |over |th||e"}); + cx.set_state( + indoc! {" + |The quick-brown + + + fox_jumps over + the"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets { cx.simulate_keystroke("shift-W"); @@ -277,13 +290,22 @@ mod test { #[gpui::test] async fn test_next_word_end(cx: &mut gpui::TestAppContext) { - let (initial_content, cursor_offsets) = marked_text(indoc! {" + let mut cx = VimTestContext::new(cx, true).await; + let (_, cursor_offsets) = marked_text(indoc! {" Th|e quic|k|-brow|n fox_jump|s ove|r th|e"}); - let mut cx = VimTestContext::new(cx, true, &initial_content).await; + cx.set_state( + indoc! {" + |The quick-brown + + + fox_jumps over + the"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets { cx.simulate_keystroke("e"); @@ -291,13 +313,21 @@ mod test { } // Reset and test ignoring punctuation - cx.simulate_keystrokes(["g", "g", "0"]); let (_, cursor_offsets) = marked_text(indoc! {" Th|e quick-brow|n fox_jump|s ove|r th||e"}); + cx.set_state( + indoc! {" + |The quick-brown + + + fox_jumps over + the"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets { cx.simulate_keystroke("shift-E"); cx.assert_newest_selection_head_offset(cursor_offset); @@ -306,14 +336,22 @@ mod test { #[gpui::test] async fn test_previous_word_start(cx: &mut gpui::TestAppContext) { - let (initial_content, cursor_offsets) = marked_text(indoc! {" + let mut cx = VimTestContext::new(cx, true).await; + let (_, cursor_offsets) = marked_text(indoc! {" ||The |quick|-|brown | | |fox_jumps |over |the"}); - let mut cx = VimTestContext::new(cx, true, &initial_content).await; - cx.simulate_keystrokes(["shift-G", "shift-$"]); + cx.set_state( + indoc! {" + The quick-brown + + + fox_jumps over + th|e"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets.into_iter().rev() { cx.simulate_keystroke("b"); @@ -321,13 +359,21 @@ mod test { } // Reset and test ignoring punctuation - cx.simulate_keystrokes(["shift-G", "shift-$"]); let (_, cursor_offsets) = marked_text(indoc! {" ||The |quick-brown | | |fox_jumps |over |the"}); + cx.set_state( + indoc! {" + The quick-brown + + + fox_jumps over + th|e"}, + Mode::Normal, + ); for cursor_offset in cursor_offsets.into_iter().rev() { cx.simulate_keystroke("shift-B"); cx.assert_newest_selection_head_offset(cursor_offset); @@ -336,7 +382,7 @@ mod test { #[gpui::test] async fn test_g_prefix_and_abort(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "").await; + let mut cx = VimTestContext::new(cx, true).await; // Can abort with escape to get back to normal mode cx.simulate_keystroke("g"); @@ -352,455 +398,55 @@ mod test { #[gpui::test] async fn test_move_to_start(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "").await; - - cx.set_state( + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["g", "g"]); + cx.assert( indoc! {" - The q|uick + The quick - brown fox jumps - over the lazy dog"}, - Mode::Normal, - ); - - // Jump to the end to - cx.simulate_keystroke("shift-G"); - cx.assert_editor_state(indoc! {" - The quick - - brown fox jumps - over |the lazy dog"}); - - // Jump to the start - cx.simulate_keystrokes(["g", "g"]); - cx.assert_editor_state(indoc! {" - The q|uick - - brown fox jumps - over the lazy dog"}); - assert_eq!(cx.mode(), Normal); - assert_eq!(cx.active_operator(), None); - - // Repeat action doesn't change - cx.simulate_keystrokes(["g", "g"]); - cx.assert_editor_state(indoc! {" - The q|uick - - brown fox jumps - over the lazy dog"}); - assert_eq!(cx.mode(), Normal); - assert_eq!(cx.active_operator(), None); - } - - #[gpui::test] - async fn test_change(cx: &mut gpui::TestAppContext) { - fn assert(motion: &str, initial_state: &str, state_after: &str, cx: &mut VimTestContext) { - cx.assert_binding( - ["c", motion], - initial_state, - Mode::Normal, - state_after, - Mode::Insert, - ); - } - let cx = &mut VimTestContext::new(cx, true, "").await; - assert("h", "Te|st", "T|st", cx); - assert("l", "Te|st", "Te|t", cx); - assert("w", "|Test", "|", cx); - assert("w", "Te|st", "Te|", cx); - assert("w", "Te|st Test", "Te| Test", cx); - assert("e", "Te|st Test", "Te| Test", cx); - assert("b", "Te|st", "|st", cx); - assert("b", "Test Te|st", "Test |st", cx); - assert( - "w", - indoc! {" - The quick - brown |fox - jumps over"}, - indoc! {" - The quick - brown | - jumps over"}, - cx, - ); - assert( - "shift-W", - indoc! {" - The quick - brown |fox-fox - jumps over"}, - indoc! {" - The quick - brown | - jumps over"}, - cx, - ); - assert( - "k", - indoc! {" - The quick - brown |fox"}, - indoc! {" - |"}, - cx, - ); - assert( - "j", - indoc! {" - The q|uick - brown fox"}, - indoc! {" - |"}, - cx, - ); - assert( - "shift-$", - indoc! {" - The q|uick - brown fox"}, - indoc! {" - The q| - brown fox"}, - cx, - ); - assert( - "0", - indoc! {" - The q|uick - brown fox"}, - indoc! {" - |uick - brown fox"}, - cx, - ); - } - - #[gpui::test] - async fn test_delete(cx: &mut gpui::TestAppContext) { - fn assert(motion: &str, initial_state: &str, state_after: &str, cx: &mut VimTestContext) { - cx.assert_binding( - ["d", motion], - initial_state, - Mode::Normal, - state_after, - Mode::Normal, - ); - } - let cx = &mut VimTestContext::new(cx, true, "").await; - assert("h", "Te|st", "T|st", cx); - assert("l", "Te|st", "Te|t", cx); - assert("w", "|Test", "|", cx); - assert("w", "Te|st", "T|e", cx); - assert("w", "Te|st Test", "Te|Test", cx); - assert("e", "Te|st Test", "Te| Test", cx); - assert("b", "Te|st", "|st", cx); - assert("b", "Test Te|st", "Test |st", cx); - assert( - "w", - indoc! {" - The quick - brown |fox - jumps over"}, - // Trailing space after cursor - indoc! {" - The quick - brown| - jumps over"}, - cx, - ); - assert( - "shift-W", - indoc! {" - The quick - brown |fox-fox - jumps over"}, - // Trailing space after cursor - indoc! {" - The quick - brown| - jumps over"}, - cx, - ); - assert( - "shift-$", - indoc! {" - The q|uick - brown fox"}, - indoc! {" - The |q - brown fox"}, - cx, - ); - assert( - "0", - indoc! {" - The q|uick - brown fox"}, - indoc! {" - |uick - brown fox"}, - cx, - ); - } - - #[gpui::test] - async fn test_linewise_delete(cx: &mut gpui::TestAppContext) { - fn assert(motion: &str, initial_state: &str, state_after: &str, cx: &mut VimTestContext) { - cx.assert_binding( - ["d", motion], - initial_state, - Mode::Normal, - state_after, - Mode::Normal, - ); - } - let cx = &mut VimTestContext::new(cx, true, "").await; - assert( - "k", - indoc! {" - The quick - brown |fox - jumps over"}, - indoc! {" - jumps |over"}, - cx, - ); - assert( - "k", - indoc! {" - The quick - brown fox - jumps |over"}, - indoc! {" - The qu|ick"}, - cx, - ); - assert( - "j", + brown fox jumps + over |the lazy dog"}, indoc! {" - The q|uick - brown fox - jumps over"}, - indoc! {" - jumps| over"}, - cx, - ); - assert( - "j", - indoc! {" - The quick - brown| fox - jumps over"}, - indoc! {" - The q|uick"}, - cx, - ); - assert( - "j", - indoc! {" - The quick - brown| fox - jumps over"}, - indoc! {" - The q|uick"}, - cx, - ); - cx.assert_binding( - ["d", "g", "g"], - indoc! {" - The quick - brown| fox - jumps over - the lazy"}, - Mode::Normal, - indoc! {" - jumps| over - the lazy"}, - Mode::Normal, - ); - cx.assert_binding( - ["d", "g", "g"], - indoc! {" - The quick - brown fox - jumps over - the l|azy"}, - Mode::Normal, - "|", - Mode::Normal, - ); - assert( - "shift-G", - indoc! {" - The quick - brown| fox - jumps over - the lazy"}, - indoc! {" - The q|uick"}, - cx, - ); - cx.assert_binding( - ["d", "g", "g"], - indoc! {" - The q|uick - brown fox - jumps over - the lazy"}, - Mode::Normal, - indoc! {" - brown| fox - jumps over - the lazy"}, - Mode::Normal, - ); - } - - #[gpui::test] - async fn test_linewise_change(cx: &mut gpui::TestAppContext) { - fn assert(motion: &str, initial_state: &str, state_after: &str, cx: &mut VimTestContext) { - cx.assert_binding( - ["c", motion], - initial_state, - Mode::Normal, - state_after, - Mode::Insert, - ); - } - let cx = &mut VimTestContext::new(cx, true, "").await; - assert( - "k", - indoc! {" - The quick - brown |fox - jumps over"}, - indoc! {" - | - jumps over"}, - cx, - ); - assert( - "k", - indoc! {" - The quick - brown fox - jumps |over"}, - indoc! {" - The quick - |"}, - cx, - ); - assert( - "j", - indoc! {" - The q|uick - brown fox - jumps over"}, - indoc! {" - | - jumps over"}, - cx, - ); - assert( - "j", - indoc! {" - The quick - brown| fox - jumps over"}, - indoc! {" - The quick - |"}, - cx, - ); - assert( - "j", - indoc! {" - The quick - brown| fox - jumps over"}, - indoc! {" - The quick - |"}, - cx, - ); - assert( - "shift-G", - indoc! {" - The quick - brown| fox - jumps over - the lazy"}, - indoc! {" - The quick - |"}, - cx, - ); - assert( - "shift-G", - indoc! {" - The quick - brown| fox - jumps over - the lazy"}, - indoc! {" - The quick - |"}, - cx, + The q|uick + + brown fox jumps + over the lazy dog"}, ); - assert( - "shift-G", + cx.assert( indoc! {" - The quick - brown fox - jumps over - the l|azy"}, + The q|uick + + brown fox jumps + over the lazy dog"}, indoc! {" - The quick - brown fox - jumps over - |"}, - cx, + The q|uick + + brown fox jumps + over the lazy dog"}, ); - cx.assert_binding( - ["c", "g", "g"], + cx.assert( indoc! {" - The quick - brown| fox - jumps over - the lazy"}, - Mode::Normal, - indoc! {" - | - jumps over - the lazy"}, - Mode::Insert, - ); - cx.assert_binding( - ["c", "g", "g"], + The quick + + brown fox jumps + over the la|zy dog"}, indoc! {" - The quick - brown fox - jumps over - the l|azy"}, - Mode::Normal, - "|", - Mode::Insert, + The quic|k + + brown fox jumps + over the lazy dog"}, ); - cx.assert_binding( - ["c", "g", "g"], + cx.assert( indoc! {" - The q|uick - brown fox - jumps over - the lazy"}, - Mode::Normal, + + + brown fox jumps + over the la|zy dog"}, indoc! {" - | - brown fox - jumps over - the lazy"}, - Mode::Insert, + | + + brown fox jumps + over the lazy dog"}, ); } } diff --git a/crates/vim/src/normal/change.rs b/crates/vim/src/normal/change.rs new file mode 100644 index 0000000000000000000000000000000000000000..daca2174e57db9f9cc3cdea4ca182f28b19f509a --- /dev/null +++ b/crates/vim/src/normal/change.rs @@ -0,0 +1,436 @@ +use crate::{motion::Motion, state::Mode, Vim}; +use editor::{char_kind, movement}; +use gpui::{impl_actions, MutableAppContext, ViewContext}; +use serde::Deserialize; +use workspace::Workspace; + +#[derive(Clone, Deserialize)] +#[serde(rename_all = "camelCase")] +struct ChangeWord { + #[serde(default)] + ignore_punctuation: bool, +} + +impl_actions!(vim, [ChangeWord]); + +pub fn init(cx: &mut MutableAppContext) { + cx.add_action(change_word); +} + +pub fn change_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { + vim.update_active_editor(cx, |editor, cx| { + editor.transact(cx, |editor, cx| { + // We are swapping to insert mode anyway. Just set the line end clipping behavior now + editor.set_clip_at_line_ends(false, cx); + editor.move_selections(cx, |map, selection| { + motion.expand_selection(map, selection, false); + }); + editor.insert(&"", cx); + }); + }); + vim.switch_mode(Mode::Insert, cx) +} + +// From the docs https://vimhelp.org/change.txt.html#cw +// Special case: When the cursor is in a word, "cw" and "cW" do not include the +// white space after a word, they only change up to the end of the word. This is +// because Vim interprets "cw" as change-word, and a word does not include the +// following white space. +fn change_word( + _: &mut Workspace, + &ChangeWord { ignore_punctuation }: &ChangeWord, + cx: &mut ViewContext, +) { + Vim::update(cx, |vim, cx| { + vim.update_active_editor(cx, |editor, cx| { + editor.transact(cx, |editor, cx| { + // We are swapping to insert mode anyway. Just set the line end clipping behavior now + editor.set_clip_at_line_ends(false, cx); + editor.move_selections(cx, |map, selection| { + if selection.end.column() == map.line_len(selection.end.row()) { + return; + } + + selection.end = movement::find_boundary(map, selection.end, |left, right| { + let left_kind = char_kind(left).coerce_punctuation(ignore_punctuation); + let right_kind = char_kind(right).coerce_punctuation(ignore_punctuation); + + left_kind != right_kind || left == '\n' || right == '\n' + }); + }); + editor.insert(&"", cx); + }); + }); + vim.switch_mode(Mode::Insert, cx); + }); +} + +#[cfg(test)] +mod test { + use indoc::indoc; + + use crate::{state::Mode, vim_test_context::VimTestContext}; + + #[gpui::test] + async fn test_change_h(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "h"]).mode_after(Mode::Insert); + cx.assert("Te|st", "T|st"); + cx.assert("T|est", "|est"); + cx.assert("|Test", "|Test"); + cx.assert( + indoc! {" + Test + |test"}, + indoc! {" + Test + |test"}, + ); + } + + #[gpui::test] + async fn test_change_l(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "l"]).mode_after(Mode::Insert); + cx.assert("Te|st", "Te|t"); + cx.assert("Tes|t", "Tes|"); + } + + #[gpui::test] + async fn test_change_w(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "w"]).mode_after(Mode::Insert); + cx.assert("Te|st", "Te|"); + cx.assert("T|est test", "T| test"); + cx.assert("Test| test", "Test|test"); + cx.assert( + indoc! {" + Test te|st + test"}, + indoc! {" + Test te| + test"}, + ); + cx.assert( + indoc! {" + Test tes|t + test"}, + indoc! {" + Test tes| + test"}, + ); + cx.assert( + indoc! {" + Test test + | + test"}, + indoc! {" + Test test + | + test"}, + ); + + let mut cx = cx.binding(["c", "shift-W"]); + cx.assert("Test te|st-test test", "Test te| test"); + } + + #[gpui::test] + async fn test_change_e(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "e"]).mode_after(Mode::Insert); + cx.assert("Te|st Test", "Te| Test"); + cx.assert("T|est test", "T| test"); + cx.assert( + indoc! {" + Test te|st + test"}, + indoc! {" + Test te| + test"}, + ); + cx.assert( + indoc! {" + Test tes|t + test"}, + "Test tes|", + ); + cx.assert( + indoc! {" + Test test + | + test"}, + indoc! {" + Test test + | + test"}, + ); + + let mut cx = cx.binding(["c", "shift-E"]); + cx.assert("Test te|st-test test", "Test te| test"); + } + + #[gpui::test] + async fn test_change_b(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "b"]).mode_after(Mode::Insert); + cx.assert("Te|st Test", "|st Test"); + cx.assert("Test |test", "|test"); + cx.assert("Test1 test2 |test3", "Test1 |test3"); + cx.assert( + indoc! {" + Test test + |test"}, + indoc! {" + Test | + test"}, + ); + cx.assert( + indoc! {" + Test test + | + test"}, + indoc! {" + Test | + + test"}, + ); + + let mut cx = cx.binding(["c", "shift-B"]); + cx.assert("Test test-test |test", "Test |test"); + } + + #[gpui::test] + async fn test_change_end_of_line(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "shift-$"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The q|uick + brown fox"}, + indoc! {" + The q| + brown fox"}, + ); + cx.assert( + indoc! {" + The quick + | + brown fox"}, + indoc! {" + The quick + | + brown fox"}, + ); + } + + #[gpui::test] + async fn test_change_0(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "0"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The q|uick + brown fox"}, + indoc! {" + |uick + brown fox"}, + ); + cx.assert( + indoc! {" + The quick + | + brown fox"}, + indoc! {" + The quick + | + brown fox"}, + ); + } + + #[gpui::test] + async fn test_change_k(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "k"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The quick + brown |fox + jumps over"}, + indoc! {" + | + jumps over"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps |over"}, + indoc! {" + The quick + |"}, + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over"}, + indoc! {" + | + brown fox + jumps over"}, + ); + cx.assert( + indoc! {" + | + brown fox + jumps over"}, + indoc! {" + | + brown fox + jumps over"}, + ); + } + + #[gpui::test] + async fn test_change_j(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "j"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The quick + brown |fox + jumps over"}, + indoc! {" + The quick + |"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps |over"}, + indoc! {" + The quick + brown fox + |"}, + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over"}, + indoc! {" + | + jumps over"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + |"}, + indoc! {" + The quick + brown fox + |"}, + ); + } + + #[gpui::test] + async fn test_change_end_of_document(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "shift-G"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + indoc! {" + The quick + |"}, + ); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + indoc! {" + The quick + |"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + the l|azy"}, + indoc! {" + The quick + brown fox + jumps over + |"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + |"}, + indoc! {" + The quick + brown fox + jumps over + |"}, + ); + } + + #[gpui::test] + async fn test_change_gg(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["c", "g", "g"]).mode_after(Mode::Insert); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + indoc! {" + | + jumps over + the lazy"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + the l|azy"}, + "|", + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over + the lazy"}, + indoc! {" + | + brown fox + jumps over + the lazy"}, + ); + cx.assert( + indoc! {" + | + brown fox + jumps over + the lazy"}, + indoc! {" + | + brown fox + jumps over + the lazy"}, + ); + } +} diff --git a/crates/vim/src/normal/delete.rs b/crates/vim/src/normal/delete.rs new file mode 100644 index 0000000000000000000000000000000000000000..8516b5ee946cc0bf8ae91ee6edd3bf850f82c5e7 --- /dev/null +++ b/crates/vim/src/normal/delete.rs @@ -0,0 +1,386 @@ +use crate::{motion::Motion, Vim}; +use editor::Bias; +use gpui::MutableAppContext; +use language::SelectionGoal; + +pub fn delete_over(vim: &mut Vim, motion: Motion, cx: &mut MutableAppContext) { + vim.update_active_editor(cx, |editor, cx| { + editor.transact(cx, |editor, cx| { + editor.set_clip_at_line_ends(false, cx); + editor.move_selections(cx, |map, selection| { + let original_head = selection.head(); + motion.expand_selection(map, selection, true); + selection.goal = SelectionGoal::Column(original_head.column()); + }); + editor.insert(&"", cx); + + // Fixup cursor position after the deletion + editor.set_clip_at_line_ends(true, cx); + editor.move_cursors(cx, |map, mut cursor, goal| { + if motion.linewise() { + if let SelectionGoal::Column(column) = goal { + *cursor.column_mut() = column + } + } + + (map.clip_point(cursor, Bias::Left), SelectionGoal::None) + }); + }); + }); +} + +#[cfg(test)] +mod test { + use indoc::indoc; + + use crate::vim_test_context::VimTestContext; + + #[gpui::test] + async fn test_delete_h(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "h"]); + cx.assert("Te|st", "T|st"); + cx.assert("T|est", "|est"); + cx.assert("|Test", "|Test"); + cx.assert( + indoc! {" + Test + |test"}, + indoc! {" + Test + |test"}, + ); + } + + #[gpui::test] + async fn test_delete_l(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "l"]); + cx.assert("|Test", "|est"); + cx.assert("Te|st", "Te|t"); + cx.assert("Tes|t", "Te|s"); + cx.assert( + indoc! {" + Tes|t + test"}, + indoc! {" + Te|s + test"}, + ); + } + + #[gpui::test] + async fn test_delete_w(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "w"]); + cx.assert("Te|st", "T|e"); + cx.assert("T|est test", "T|test"); + cx.assert( + indoc! {" + Test te|st + test"}, + indoc! {" + Test t|e + test"}, + ); + cx.assert( + indoc! {" + Test tes|t + test"}, + indoc! {" + Test te|s + test"}, + ); + cx.assert( + indoc! {" + Test test + | + test"}, + indoc! {" + Test test + | + test"}, + ); + + let mut cx = cx.binding(["d", "shift-W"]); + cx.assert("Test te|st-test test", "Test te|test"); + } + + #[gpui::test] + async fn test_delete_e(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "e"]); + cx.assert("Te|st Test", "Te| Test"); + cx.assert("T|est test", "T| test"); + cx.assert( + indoc! {" + Test te|st + test"}, + indoc! {" + Test t|e + test"}, + ); + cx.assert( + indoc! {" + Test tes|t + test"}, + "Test te|s", + ); + cx.assert( + indoc! {" + Test test + | + test"}, + indoc! {" + Test test + | + test"}, + ); + + let mut cx = cx.binding(["d", "shift-E"]); + cx.assert("Test te|st-test test", "Test te| test"); + } + + #[gpui::test] + async fn test_delete_b(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "b"]); + cx.assert("Te|st Test", "|st Test"); + cx.assert("Test |test", "|test"); + cx.assert("Test1 test2 |test3", "Test1 |test3"); + cx.assert( + indoc! {" + Test test + |test"}, + // Trailing whitespace after cursor + indoc! {" + Test| + test"}, + ); + cx.assert( + indoc! {" + Test test + | + test"}, + // Trailing whitespace after cursor + indoc! {" + Test| + + test"}, + ); + + let mut cx = cx.binding(["d", "shift-B"]); + cx.assert("Test test-test |test", "Test |test"); + } + + #[gpui::test] + async fn test_delete_end_of_line(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "shift-$"]); + cx.assert( + indoc! {" + The q|uick + brown fox"}, + indoc! {" + The |q + brown fox"}, + ); + cx.assert( + indoc! {" + The quick + | + brown fox"}, + indoc! {" + The quick + | + brown fox"}, + ); + } + + #[gpui::test] + async fn test_delete_0(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "0"]); + cx.assert( + indoc! {" + The q|uick + brown fox"}, + indoc! {" + |uick + brown fox"}, + ); + cx.assert( + indoc! {" + The quick + | + brown fox"}, + indoc! {" + The quick + | + brown fox"}, + ); + } + + #[gpui::test] + async fn test_delete_k(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "k"]); + cx.assert( + indoc! {" + The quick + brown |fox + jumps over"}, + "jumps |over", + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps |over"}, + "The qu|ick", + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over"}, + indoc! {" + brown| fox + jumps over"}, + ); + cx.assert( + indoc! {" + |brown fox + jumps over"}, + "|jumps over", + ); + } + + #[gpui::test] + async fn test_delete_j(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "j"]); + cx.assert( + indoc! {" + The quick + brown |fox + jumps over"}, + "The qu|ick", + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps |over"}, + indoc! {" + The quick + brown |fox"}, + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over"}, + "jumps| over", + ); + cx.assert( + indoc! {" + The quick + brown fox + |"}, + indoc! {" + The quick + |brown fox"}, + ); + } + + #[gpui::test] + async fn test_delete_end_of_document(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "shift-G"]); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + "The q|uick", + ); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + "The q|uick", + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + the l|azy"}, + indoc! {" + The quick + brown fox + jumps| over"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + |"}, + indoc! {" + The quick + brown fox + |jumps over"}, + ); + } + + #[gpui::test] + async fn test_delete_gg(cx: &mut gpui::TestAppContext) { + let cx = VimTestContext::new(cx, true).await; + let mut cx = cx.binding(["d", "g", "g"]); + cx.assert( + indoc! {" + The quick + brown| fox + jumps over + the lazy"}, + indoc! {" + jumps| over + the lazy"}, + ); + cx.assert( + indoc! {" + The quick + brown fox + jumps over + the l|azy"}, + "|", + ); + cx.assert( + indoc! {" + The q|uick + brown fox + jumps over + the lazy"}, + indoc! {" + brown| fox + jumps over + the lazy"}, + ); + cx.assert( + indoc! {" + | + brown fox + jumps over + the lazy"}, + indoc! {" + |brown fox + jumps over + the lazy"}, + ); + } +} diff --git a/crates/vim/src/vim.rs b/crates/vim/src/vim.rs index 65acce7a42606ef17bf2b750de92b212c756c85d..527cfa318c8d3ca585c29003ae7c96d6fad2d46c 100644 --- a/crates/vim/src/vim.rs +++ b/crates/vim/src/vim.rs @@ -1,10 +1,11 @@ +#[cfg(test)] +mod vim_test_context; + mod editor_events; mod insert; mod motion; mod normal; mod state; -#[cfg(test)] -mod vim_test_context; use collections::HashMap; use editor::{CursorShape, Editor}; @@ -25,6 +26,7 @@ impl_actions!(vim, [SwitchMode, PushOperator]); pub fn init(cx: &mut MutableAppContext) { editor_events::init(cx); + normal::init(cx); insert::init(cx); motion::init(cx); @@ -142,14 +144,14 @@ mod test { #[gpui::test] async fn test_initially_disabled(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, false, "").await; + let mut cx = VimTestContext::new(cx, false).await; cx.simulate_keystrokes(["h", "j", "k", "l"]); cx.assert_editor_state("hjkl|"); } #[gpui::test] async fn test_toggle_through_settings(cx: &mut gpui::TestAppContext) { - let mut cx = VimTestContext::new(cx, true, "").await; + let mut cx = VimTestContext::new(cx, true).await; cx.simulate_keystroke("i"); assert_eq!(cx.mode(), Mode::Insert); diff --git a/crates/vim/src/vim_test_context.rs b/crates/vim/src/vim_test_context.rs index cceedd712089d540d3333b50cb3d82095d73e91e..400a8e467a881c78c427c82f4e1e7414cf0d2dba 100644 --- a/crates/vim/src/vim_test_context.rs +++ b/crates/vim/src/vim_test_context.rs @@ -15,11 +15,7 @@ pub struct VimTestContext<'a> { } impl<'a> VimTestContext<'a> { - pub async fn new( - cx: &'a mut gpui::TestAppContext, - enabled: bool, - initial_editor_text: &str, - ) -> VimTestContext<'a> { + pub async fn new(cx: &'a mut gpui::TestAppContext, enabled: bool) -> VimTestContext<'a> { cx.update(|cx| { editor::init(cx); crate::init(cx); @@ -38,10 +34,7 @@ impl<'a> VimTestContext<'a> { params .fs .as_fake() - .insert_tree( - "/root", - json!({ "dir": { "test.txt": initial_editor_text } }), - ) + .insert_tree("/root", json!({ "dir": { "test.txt": "" } })) .await; let (window_id, workspace) = cx.add_window(|cx| Workspace::new(¶ms, cx)); @@ -202,6 +195,14 @@ impl<'a> VimTestContext<'a> { assert_eq!(self.mode(), mode_after); assert_eq!(self.active_operator(), None); } + + pub fn binding( + mut self, + keystrokes: [&'static str; COUNT], + ) -> VimBindingTestContext<'a, COUNT> { + let mode = self.mode(); + VimBindingTestContext::new(keystrokes, mode, mode, self) + } } impl<'a> Deref for VimTestContext<'a> { @@ -211,3 +212,61 @@ impl<'a> Deref for VimTestContext<'a> { self.cx } } + +pub struct VimBindingTestContext<'a, const COUNT: usize> { + cx: VimTestContext<'a>, + keystrokes_under_test: [&'static str; COUNT], + initial_mode: Mode, + mode_after: Mode, +} + +impl<'a, const COUNT: usize> VimBindingTestContext<'a, COUNT> { + pub fn new( + keystrokes_under_test: [&'static str; COUNT], + initial_mode: Mode, + mode_after: Mode, + cx: VimTestContext<'a>, + ) -> Self { + Self { + cx, + keystrokes_under_test, + initial_mode, + mode_after, + } + } + + pub fn binding( + self, + keystrokes_under_test: [&'static str; NEW_COUNT], + ) -> VimBindingTestContext<'a, NEW_COUNT> { + VimBindingTestContext { + keystrokes_under_test, + cx: self.cx, + initial_mode: self.initial_mode, + mode_after: self.mode_after, + } + } + + pub fn mode_after(mut self, mode_after: Mode) -> Self { + self.mode_after = mode_after; + self + } + + pub fn assert(&mut self, initial_state: &str, state_after: &str) { + self.cx.assert_binding( + self.keystrokes_under_test, + initial_state, + self.initial_mode, + state_after, + self.mode_after, + ) + } +} + +impl<'a, const COUNT: usize> Deref for VimBindingTestContext<'a, COUNT> { + type Target = VimTestContext<'a>; + + fn deref(&self) -> &Self::Target { + &self.cx + } +} diff --git a/crates/workspace/src/workspace.rs b/crates/workspace/src/workspace.rs index e8048e0953048e0b0de4c7969278aef50c279cc6..1c0a92823c88227b955ca212cc44ab055d130e40 100644 --- a/crates/workspace/src/workspace.rs +++ b/crates/workspace/src/workspace.rs @@ -1297,7 +1297,7 @@ impl Workspace { if project.is_local() { if project.is_shared() { project.unshare(cx); - } else { + } else if project.can_share(cx) { project.share(cx).detach(); } } @@ -1475,28 +1475,38 @@ impl Workspace { } fn render_titlebar(&self, theme: &Theme, cx: &mut RenderContext) -> ElementBox { + let mut worktree_root_names = String::new(); + { + let mut worktrees = self.project.read(cx).visible_worktrees(cx).peekable(); + while let Some(worktree) = worktrees.next() { + worktree_root_names.push_str(worktree.read(cx).root_name()); + if worktrees.peek().is_some() { + worktree_root_names.push_str(", "); + } + } + } + ConstrainedBox::new( Container::new( Stack::new() .with_child( - Align::new( - Label::new("zed".into(), theme.workspace.titlebar.title.clone()) - .boxed(), - ) - .boxed(), + Label::new(worktree_root_names, theme.workspace.titlebar.title.clone()) + .aligned() + .left() + .boxed(), ) .with_child( Align::new( Flex::row() - .with_children(self.render_share_icon(theme, cx)) .with_children(self.render_collaborators(theme, cx)) - .with_child(self.render_current_user( + .with_children(self.render_current_user( self.user_store.read(cx).current_user().as_ref(), self.project.read(cx).replica_id(), theme, cx, )) .with_children(self.render_connection_status(cx)) + .with_children(self.render_share_icon(theme, cx)) .boxed(), ) .right() @@ -1540,25 +1550,30 @@ impl Workspace { replica_id: ReplicaId, theme: &Theme, cx: &mut RenderContext, - ) -> ElementBox { + ) -> Option { + let status = *self.client.status().borrow(); if let Some(avatar) = user.and_then(|user| user.avatar.clone()) { - self.render_avatar(avatar, replica_id, None, theme, cx) + Some(self.render_avatar(avatar, replica_id, None, theme, cx)) + } else if matches!(status, client::Status::UpgradeRequired) { + None } else { - MouseEventHandler::new::(0, cx, |state, _| { - let style = if state.hovered { - &theme.workspace.titlebar.hovered_sign_in_prompt - } else { - &theme.workspace.titlebar.sign_in_prompt - }; - Label::new("Sign in".to_string(), style.text.clone()) - .contained() - .with_style(style.container) - .boxed() - }) - .on_click(|cx| cx.dispatch_action(Authenticate)) - .with_cursor_style(CursorStyle::PointingHand) - .aligned() - .boxed() + Some( + MouseEventHandler::new::(0, cx, |state, _| { + let style = if state.hovered { + &theme.workspace.titlebar.hovered_sign_in_prompt + } else { + &theme.workspace.titlebar.sign_in_prompt + }; + Label::new("Sign in".to_string(), style.text.clone()) + .contained() + .with_style(style.container) + .boxed() + }) + .on_click(|cx| cx.dispatch_action(Authenticate)) + .with_cursor_style(CursorStyle::PointingHand) + .aligned() + .boxed(), + ) } } @@ -1598,6 +1613,8 @@ impl Workspace { ) .constrained() .with_width(theme.workspace.right_sidebar.width) + .contained() + .with_margin_left(2.) .boxed(); if let Some(peer_id) = peer_id { @@ -1611,22 +1628,39 @@ impl Workspace { } fn render_share_icon(&self, theme: &Theme, cx: &mut RenderContext) -> Option { - if self.project().read(cx).is_local() && self.client.user_id().is_some() { - let color = if self.project().read(cx).is_shared() { - theme.workspace.titlebar.share_icon_active_color - } else { - theme.workspace.titlebar.share_icon_color - }; + if self.project().read(cx).is_local() + && self.client.user_id().is_some() + && self.project().read(cx).can_share(cx) + { Some( - MouseEventHandler::new::(0, cx, |_, _| { - Align::new( - Svg::new("icons/broadcast-24.svg") - .with_color(color) - .constrained() - .with_width(24.) - .boxed(), - ) - .boxed() + MouseEventHandler::new::(0, cx, |state, cx| { + let style = if self.project().read(cx).is_shared() { + if state.hovered { + &theme.workspace.titlebar.hovered_active_share_icon + } else { + &theme.workspace.titlebar.active_share_icon + } + } else { + if state.hovered { + &theme.workspace.titlebar.hovered_share_icon + } else { + &theme.workspace.titlebar.share_icon + } + }; + Svg::new("icons/share.svg") + .with_color(style.color) + .constrained() + .with_height(14.) + .aligned() + .contained() + .with_style(style.container) + .constrained() + .with_width(24.) + .aligned() + .constrained() + .with_width(theme.workspace.right_sidebar.width) + .aligned() + .boxed() }) .with_cursor_style(CursorStyle::PointingHand) .on_click(|cx| cx.dispatch_action(ToggleShare)) @@ -1983,7 +2017,14 @@ impl View for Workspace { content.add_child(self.right_sidebar.render(&theme, cx)); content.boxed() }) - .with_children(self.modal.as_ref().map(|m| ChildView::new(m).boxed())) + .with_children(self.modal.as_ref().map(|m| { + ChildView::new(m) + .contained() + .with_style(theme.workspace.modal) + .aligned() + .top() + .boxed() + })) .flex(1.0, true) .boxed(), ) diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 2f0310fd4572c160cd213951008c900cf9cd020c..7ec7c78a9356ab9a1f9e7ebaaa0874bdb8cc9964 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -3,7 +3,7 @@ authors = ["Nathan Sobo "] description = "The fast, collaborative code editor." edition = "2021" name = "zed" -version = "0.29.0" +version = "0.30.0" [lib] name = "zed" diff --git a/crates/zed/src/languages.rs b/crates/zed/src/languages.rs index d0d6de989a717c8c2de4bd2ebade9c8af9b13672..36900e3e71f06a2f0a023bd303512acac6f94824 100644 --- a/crates/zed/src/languages.rs +++ b/crates/zed/src/languages.rs @@ -63,7 +63,7 @@ pub fn build_language_registry(login_shell_env_loaded: Task<()>) -> LanguageRegi languages } -fn language( +pub(crate) fn language( name: &str, grammar: tree_sitter::Language, lsp_adapter: Option>, diff --git a/crates/zed/src/languages/c/highlights.scm b/crates/zed/src/languages/c/highlights.scm index 9f2dabff174eb9f0b12d621d69c4786c88f94e94..4a9c7bf2eaefc6262db4d37c56415bb31ae9460a 100644 --- a/crates/zed/src/languages/c/highlights.scm +++ b/crates/zed/src/languages/c/highlights.scm @@ -56,7 +56,16 @@ [ "." ";" -] @delimiter +] @punctuation.delimiter + +[ + "{" + "}" + "(" + ")" + "[" + "]" +] @punctuation.bracket [ (string_literal) diff --git a/crates/zed/src/languages/javascript/highlights.scm b/crates/zed/src/languages/javascript/highlights.scm index cb4e82b33d8b04da41e90c6926499669fee33b60..d3921cdbc8096ce2a21acd28325c89cf14a383cc 100644 --- a/crates/zed/src/languages/javascript/highlights.scm +++ b/crates/zed/src/languages/javascript/highlights.scm @@ -86,6 +86,7 @@ "?." "." "," + ":" ] @punctuation.delimiter [ diff --git a/crates/zed/src/languages/json/highlights.scm b/crates/zed/src/languages/json/highlights.scm index 9754465166f191cf19b2c92105396ccd170cef43..b5c64e96344cfbdeaa6dfe35a8bdca99b6c891e5 100644 --- a/crates/zed/src/languages/json/highlights.scm +++ b/crates/zed/src/languages/json/highlights.scm @@ -11,4 +11,11 @@ (true) (false) (null) -] @constant \ No newline at end of file +] @constant + +[ + "{" + "}" + "[" + "]" +] @punctuation.bracket \ No newline at end of file diff --git a/crates/zed/src/languages/markdown/highlights.scm b/crates/zed/src/languages/markdown/highlights.scm index 65ac47ec4bd5537bb5d07301bc6eb9a48124622a..83bf7b57a48df2b77648dcd33fbb8fdb675c9e51 100644 --- a/crates/zed/src/languages/markdown/highlights.scm +++ b/crates/zed/src/languages/markdown/highlights.scm @@ -12,7 +12,7 @@ (list_marker_star) (list_marker_dot) (list_marker_parenthesis) -] @list_marker +] @punctuation.list_marker [ (indented_code_block) diff --git a/crates/zed/src/languages/rust/highlights.scm b/crates/zed/src/languages/rust/highlights.scm index 116be758424216869f66772a09b11b9ab90f9da1..d4f571dd526ecd795c6307b14780caea7201d5a0 100644 --- a/crates/zed/src/languages/rust/highlights.scm +++ b/crates/zed/src/languages/rust/highlights.scm @@ -34,6 +34,20 @@ ((identifier) @constant (#match? @constant "^[A-Z][A-Z\\d_]+$")) +[ + "(" + ")" + "{" + "}" + "[" + "]" +] @punctuation.bracket + +(_ + . + "<" @punctuation.bracket + ">" @punctuation.bracket) + [ "as" "async" diff --git a/crates/zed/src/languages/toml/highlights.scm b/crates/zed/src/languages/toml/highlights.scm index 9f43b6aa6f0bd9abbbeea820c504613306dd1dff..04d83b545925d787de1ce238e88b79f234624bef 100644 --- a/crates/zed/src/languages/toml/highlights.scm +++ b/crates/zed/src/languages/toml/highlights.scm @@ -20,14 +20,18 @@ ; Punctuation ;------------ -"." @punctuation.delimiter -"," @punctuation.delimiter +[ + "." + "," +] @punctuation.delimiter "=" @operator -"[" @punctuation.bracket -"]" @punctuation.bracket -"[[" @punctuation.bracket -"]]" @punctuation.bracket -"{" @punctuation.bracket -"}" @punctuation.bracket \ No newline at end of file +[ + "[" + "]" + "[[" + "]]" + "{" + "}" +] @punctuation.bracket diff --git a/crates/zed/src/languages/typescript.rs b/crates/zed/src/languages/typescript.rs index aca8cdef52df87e5e1d566726f75901f834543c1..79c74c521d5c80cff26520c0d03a6860681e5dba 100644 --- a/crates/zed/src/languages/typescript.rs +++ b/crates/zed/src/languages/typescript.rs @@ -144,3 +144,54 @@ impl LspAdapter for TypeScriptLspAdapter { })) } } + +#[cfg(test)] +mod tests { + use std::sync::Arc; + + use gpui::MutableAppContext; + use unindent::Unindent; + + #[gpui::test] + fn test_outline(cx: &mut MutableAppContext) { + let language = crate::languages::language( + "typescript", + tree_sitter_typescript::language_typescript(), + None, + ); + + let text = r#" + function a() { + // local variables are omitted + let a1 = 1; + // all functions are included + async function a2() {} + } + // top-level variables are included + let b: C + function getB() {} + // exported variables are included + export const d = e; + "# + .unindent(); + + let buffer = cx.add_model(|cx| { + language::Buffer::new(0, text, cx).with_language(Arc::new(language), cx) + }); + let outline = buffer.read(cx).snapshot().outline(None).unwrap(); + assert_eq!( + outline + .items + .iter() + .map(|item| (item.text.as_str(), item.depth)) + .collect::>(), + &[ + ("function a ( )", 0), + ("async function a2 ( )", 1), + ("let b", 0), + ("function getB ( )", 0), + ("const d", 0), + ] + ); + } +} diff --git a/crates/zed/src/languages/typescript/highlights.scm b/crates/zed/src/languages/typescript/highlights.scm index cb4e82b33d8b04da41e90c6926499669fee33b60..d3921cdbc8096ce2a21acd28325c89cf14a383cc 100644 --- a/crates/zed/src/languages/typescript/highlights.scm +++ b/crates/zed/src/languages/typescript/highlights.scm @@ -86,6 +86,7 @@ "?." "." "," + ":" ] @punctuation.delimiter [ diff --git a/crates/zed/src/languages/typescript/outline.scm b/crates/zed/src/languages/typescript/outline.scm index f8691fa41d9f64bc71e8a7ada2e6d64d62268a3a..68d297653e1175aba7ef6651acdec7e61c9a767f 100644 --- a/crates/zed/src/languages/typescript/outline.scm +++ b/crates/zed/src/languages/typescript/outline.scm @@ -6,6 +6,10 @@ "enum" @context name: (_) @name) @item +(type_alias_declaration + "type" @context + name: (_) @name) @item + (function_declaration "async"? @context "function" @context @@ -18,6 +22,12 @@ "interface" @context name: (_) @name) @item +(export_statement + (lexical_declaration + ["let" "const"] @context + (variable_declarator + name: (_) @name) @item)) + (program (lexical_declaration ["let" "const"] @context diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index d4f06f074e1e1be0cf106392d0c6e9fb5833aef1..16df63bf200b46d57c953f94abe161e5938af3c4 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -169,11 +169,19 @@ fn main() { .detach(); languages.set_language_server_download_dir(zed::ROOT_PATH.clone()); - languages.set_theme(&settings.theme.editor.syntax); + let languages = Arc::new(languages); + + cx.observe_global::({ + let languages = languages.clone(); + move |settings, _| { + languages.set_theme(&settings.theme.editor.syntax); + } + }) + .detach(); cx.set_global(settings); let app_state = Arc::new(AppState { - languages: Arc::new(languages), + languages, themes, channel_list, client, diff --git a/styles/dist/solarized-dark.json b/styles/dist/solarized-dark.json new file mode 100644 index 0000000000000000000000000000000000000000..e5ed5d181fb7b6dfb1fa6cdfa748079be7c3798e --- /dev/null +++ b/styles/dist/solarized-dark.json @@ -0,0 +1,567 @@ +{ + "meta": { + "themeName": "solarized-dark" + }, + "text": { + "primary": { + "value": "#eee8d5", + "type": "color" + }, + "secondary": { + "value": "#93a1a1", + "type": "color" + }, + "muted": { + "value": "#93a1a1", + "type": "color" + }, + "placeholder": { + "value": "#839496", + "type": "color" + }, + "active": { + "value": "#fdf6e3", + "type": "color" + }, + "feature": { + "value": "#268bd2", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#eee8d5", + "type": "color" + }, + "secondary": { + "value": "#93a1a1", + "type": "color" + }, + "muted": { + "value": "#93a1a1", + "type": "color" + }, + "placeholder": { + "value": "#839496", + "type": "color" + }, + "active": { + "value": "#fdf6e3", + "type": "color" + }, + "feature": { + "value": "#268bd2", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#073642", + "type": "color" + }, + "hovered": { + "value": "#586e75", + "type": "color" + }, + "active": { + "value": "#586e75", + "type": "color" + }, + "focused": { + "value": "#586e75", + "type": "color" + } + }, + "300": { + "base": { + "value": "#073642", + "type": "color" + }, + "hovered": { + "value": "#586e75", + "type": "color" + }, + "active": { + "value": "#586e75", + "type": "color" + }, + "focused": { + "value": "#586e75", + "type": "color" + } + }, + "500": { + "base": { + "value": "#002b36", + "type": "color" + }, + "hovered": { + "value": "#073642", + "type": "color" + }, + "active": { + "value": "#073642", + "type": "color" + }, + "focused": { + "value": "#073642", + "type": "color" + } + }, + "on300": { + "base": { + "value": "#002b36", + "type": "color" + }, + "hovered": { + "value": "#073642", + "type": "color" + }, + "active": { + "value": "#073642", + "type": "color" + }, + "focused": { + "value": "#073642", + "type": "color" + } + }, + "on500": { + "base": { + "value": "#073642", + "type": "color" + }, + "hovered": { + "value": "#586e75", + "type": "color" + }, + "active": { + "value": "#586e75", + "type": "color" + }, + "focused": { + "value": "#586e75", + "type": "color" + } + }, + "ok": { + "base": { + "value": "#859900", + "type": "color" + }, + "hovered": { + "value": "#859900", + "type": "color" + }, + "active": { + "value": "#859900", + "type": "color" + }, + "focused": { + "value": "#859900", + "type": "color" + } + }, + "error": { + "base": { + "value": "#dc322f", + "type": "color" + }, + "hovered": { + "value": "#dc322f", + "type": "color" + }, + "active": { + "value": "#dc322f", + "type": "color" + }, + "focused": { + "value": "#dc322f", + "type": "color" + } + }, + "warning": { + "base": { + "value": "#b58900", + "type": "color" + }, + "hovered": { + "value": "#b58900", + "type": "color" + }, + "active": { + "value": "#b58900", + "type": "color" + }, + "focused": { + "value": "#b58900", + "type": "color" + } + }, + "info": { + "base": { + "value": "#268bd2", + "type": "color" + }, + "hovered": { + "value": "#268bd2", + "type": "color" + }, + "active": { + "value": "#268bd2", + "type": "color" + }, + "focused": { + "value": "#268bd2", + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#002b36", + "type": "color" + }, + "secondary": { + "value": "#073642", + "type": "color" + }, + "muted": { + "value": "#586e75", + "type": "color" + }, + "focused": { + "value": "#586e75", + "type": "color" + }, + "active": { + "value": "#586e75", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "editor": { + "background": { + "value": "#002b36", + "type": "color" + }, + "indent_guide": { + "value": "#586e75", + "type": "color" + }, + "indent_guide_active": { + "value": "#073642", + "type": "color" + }, + "line": { + "active": { + "value": "#fdf6e312", + "type": "color" + }, + "highlighted": { + "value": "#fdf6e31f", + "type": "color" + }, + "inserted": { + "value": "#859900", + "type": "color" + }, + "deleted": { + "value": "#dc322f", + "type": "color" + }, + "modified": { + "value": "#268bd2", + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#268bd23d", + "type": "color" + }, + "occurrence": { + "value": "#657b831f", + "type": "color" + }, + "activeOccurrence": { + "value": "#657b8329", + "type": "color" + }, + "matchingBracket": { + "value": "#073642", + "type": "color" + }, + "match": { + "value": "#6c71c480", + "type": "color" + }, + "activeMatch": { + "value": "#6c71c4b3", + "type": "color" + }, + "related": { + "value": "#073642", + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#839496", + "type": "color" + }, + "active": { + "value": "#fdf6e3", + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#fdf6e3", + "type": "color" + }, + "comment": { + "value": "#eee8d5", + "type": "color" + }, + "keyword": { + "value": "#268bd2", + "type": "color" + }, + "function": { + "value": "#b58900", + "type": "color" + }, + "type": { + "value": "#2aa198", + "type": "color" + }, + "variant": { + "value": "#268bd2", + "type": "color" + }, + "property": { + "value": "#268bd2", + "type": "color" + }, + "enum": { + "value": "#cb4b16", + "type": "color" + }, + "operator": { + "value": "#cb4b16", + "type": "color" + }, + "string": { + "value": "#cb4b16", + "type": "color" + }, + "number": { + "value": "#859900", + "type": "color" + }, + "boolean": { + "value": "#859900", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#268bd2", + "type": "color" + }, + "cursorColor": { + "value": "#268bd2", + "type": "color" + }, + "selectionColor": { + "value": "#268bd23d", + "type": "color" + }, + "borderColor": { + "value": "#268bd2cc", + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#859900", + "type": "color" + }, + "cursorColor": { + "value": "#859900", + "type": "color" + }, + "selectionColor": { + "value": "#8599003d", + "type": "color" + }, + "borderColor": { + "value": "#859900cc", + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#d33682", + "type": "color" + }, + "cursorColor": { + "value": "#d33682", + "type": "color" + }, + "selectionColor": { + "value": "#d336823d", + "type": "color" + }, + "borderColor": { + "value": "#d33682cc", + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#cb4b16", + "type": "color" + }, + "cursorColor": { + "value": "#cb4b16", + "type": "color" + }, + "selectionColor": { + "value": "#cb4b163d", + "type": "color" + }, + "borderColor": { + "value": "#cb4b16cc", + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#6c71c4", + "type": "color" + }, + "cursorColor": { + "value": "#6c71c4", + "type": "color" + }, + "selectionColor": { + "value": "#6c71c43d", + "type": "color" + }, + "borderColor": { + "value": "#6c71c4cc", + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#2aa198", + "type": "color" + }, + "cursorColor": { + "value": "#2aa198", + "type": "color" + }, + "selectionColor": { + "value": "#2aa1983d", + "type": "color" + }, + "borderColor": { + "value": "#2aa198cc", + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#dc322f", + "type": "color" + }, + "cursorColor": { + "value": "#dc322f", + "type": "color" + }, + "selectionColor": { + "value": "#dc322f3d", + "type": "color" + }, + "borderColor": { + "value": "#dc322fcc", + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#b58900", + "type": "color" + }, + "cursorColor": { + "value": "#b58900", + "type": "color" + }, + "selectionColor": { + "value": "#b589003d", + "type": "color" + }, + "borderColor": { + "value": "#b58900cc", + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.32, + "type": "number" + } +} \ No newline at end of file diff --git a/styles/dist/solarized-light.json b/styles/dist/solarized-light.json new file mode 100644 index 0000000000000000000000000000000000000000..73eae57a7f52889e599704d22e42363f285854b2 --- /dev/null +++ b/styles/dist/solarized-light.json @@ -0,0 +1,567 @@ +{ + "meta": { + "themeName": "solarized-light" + }, + "text": { + "primary": { + "value": "#073642", + "type": "color" + }, + "secondary": { + "value": "#586e75", + "type": "color" + }, + "muted": { + "value": "#586e75", + "type": "color" + }, + "placeholder": { + "value": "#657b83", + "type": "color" + }, + "active": { + "value": "#002b36", + "type": "color" + }, + "feature": { + "value": "#268bd2", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "icon": { + "primary": { + "value": "#073642", + "type": "color" + }, + "secondary": { + "value": "#586e75", + "type": "color" + }, + "muted": { + "value": "#586e75", + "type": "color" + }, + "placeholder": { + "value": "#657b83", + "type": "color" + }, + "active": { + "value": "#002b36", + "type": "color" + }, + "feature": { + "value": "#268bd2", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "background": { + "100": { + "base": { + "value": "#eee8d5", + "type": "color" + }, + "hovered": { + "value": "#93a1a1", + "type": "color" + }, + "active": { + "value": "#93a1a1", + "type": "color" + }, + "focused": { + "value": "#93a1a1", + "type": "color" + } + }, + "300": { + "base": { + "value": "#eee8d5", + "type": "color" + }, + "hovered": { + "value": "#93a1a1", + "type": "color" + }, + "active": { + "value": "#93a1a1", + "type": "color" + }, + "focused": { + "value": "#93a1a1", + "type": "color" + } + }, + "500": { + "base": { + "value": "#fdf6e3", + "type": "color" + }, + "hovered": { + "value": "#eee8d5", + "type": "color" + }, + "active": { + "value": "#eee8d5", + "type": "color" + }, + "focused": { + "value": "#eee8d5", + "type": "color" + } + }, + "on300": { + "base": { + "value": "#fdf6e3", + "type": "color" + }, + "hovered": { + "value": "#eee8d5", + "type": "color" + }, + "active": { + "value": "#eee8d5", + "type": "color" + }, + "focused": { + "value": "#eee8d5", + "type": "color" + } + }, + "on500": { + "base": { + "value": "#eee8d5", + "type": "color" + }, + "hovered": { + "value": "#93a1a1", + "type": "color" + }, + "active": { + "value": "#93a1a1", + "type": "color" + }, + "focused": { + "value": "#93a1a1", + "type": "color" + } + }, + "ok": { + "base": { + "value": "#859900", + "type": "color" + }, + "hovered": { + "value": "#859900", + "type": "color" + }, + "active": { + "value": "#859900", + "type": "color" + }, + "focused": { + "value": "#859900", + "type": "color" + } + }, + "error": { + "base": { + "value": "#dc322f", + "type": "color" + }, + "hovered": { + "value": "#dc322f", + "type": "color" + }, + "active": { + "value": "#dc322f", + "type": "color" + }, + "focused": { + "value": "#dc322f", + "type": "color" + } + }, + "warning": { + "base": { + "value": "#b58900", + "type": "color" + }, + "hovered": { + "value": "#b58900", + "type": "color" + }, + "active": { + "value": "#b58900", + "type": "color" + }, + "focused": { + "value": "#b58900", + "type": "color" + } + }, + "info": { + "base": { + "value": "#268bd2", + "type": "color" + }, + "hovered": { + "value": "#268bd2", + "type": "color" + }, + "active": { + "value": "#268bd2", + "type": "color" + }, + "focused": { + "value": "#268bd2", + "type": "color" + } + } + }, + "border": { + "primary": { + "value": "#fdf6e3", + "type": "color" + }, + "secondary": { + "value": "#eee8d5", + "type": "color" + }, + "muted": { + "value": "#93a1a1", + "type": "color" + }, + "focused": { + "value": "#93a1a1", + "type": "color" + }, + "active": { + "value": "#93a1a1", + "type": "color" + }, + "ok": { + "value": "#859900", + "type": "color" + }, + "error": { + "value": "#dc322f", + "type": "color" + }, + "warning": { + "value": "#b58900", + "type": "color" + }, + "info": { + "value": "#268bd2", + "type": "color" + } + }, + "editor": { + "background": { + "value": "#fdf6e3", + "type": "color" + }, + "indent_guide": { + "value": "#93a1a1", + "type": "color" + }, + "indent_guide_active": { + "value": "#eee8d5", + "type": "color" + }, + "line": { + "active": { + "value": "#002b3612", + "type": "color" + }, + "highlighted": { + "value": "#002b361f", + "type": "color" + }, + "inserted": { + "value": "#859900", + "type": "color" + }, + "deleted": { + "value": "#dc322f", + "type": "color" + }, + "modified": { + "value": "#268bd2", + "type": "color" + } + }, + "highlight": { + "selection": { + "value": "#268bd23d", + "type": "color" + }, + "occurrence": { + "value": "#8394961f", + "type": "color" + }, + "activeOccurrence": { + "value": "#83949629", + "type": "color" + }, + "matchingBracket": { + "value": "#eee8d5", + "type": "color" + }, + "match": { + "value": "#6c71c480", + "type": "color" + }, + "activeMatch": { + "value": "#6c71c4b3", + "type": "color" + }, + "related": { + "value": "#eee8d5", + "type": "color" + } + }, + "gutter": { + "primary": { + "value": "#657b83", + "type": "color" + }, + "active": { + "value": "#002b36", + "type": "color" + } + } + }, + "syntax": { + "primary": { + "value": "#002b36", + "type": "color" + }, + "comment": { + "value": "#073642", + "type": "color" + }, + "keyword": { + "value": "#268bd2", + "type": "color" + }, + "function": { + "value": "#b58900", + "type": "color" + }, + "type": { + "value": "#2aa198", + "type": "color" + }, + "variant": { + "value": "#268bd2", + "type": "color" + }, + "property": { + "value": "#268bd2", + "type": "color" + }, + "enum": { + "value": "#cb4b16", + "type": "color" + }, + "operator": { + "value": "#cb4b16", + "type": "color" + }, + "string": { + "value": "#cb4b16", + "type": "color" + }, + "number": { + "value": "#859900", + "type": "color" + }, + "boolean": { + "value": "#859900", + "type": "color" + } + }, + "player": { + "1": { + "baseColor": { + "value": "#268bd2", + "type": "color" + }, + "cursorColor": { + "value": "#268bd2", + "type": "color" + }, + "selectionColor": { + "value": "#268bd23d", + "type": "color" + }, + "borderColor": { + "value": "#268bd2cc", + "type": "color" + } + }, + "2": { + "baseColor": { + "value": "#859900", + "type": "color" + }, + "cursorColor": { + "value": "#859900", + "type": "color" + }, + "selectionColor": { + "value": "#8599003d", + "type": "color" + }, + "borderColor": { + "value": "#859900cc", + "type": "color" + } + }, + "3": { + "baseColor": { + "value": "#d33682", + "type": "color" + }, + "cursorColor": { + "value": "#d33682", + "type": "color" + }, + "selectionColor": { + "value": "#d336823d", + "type": "color" + }, + "borderColor": { + "value": "#d33682cc", + "type": "color" + } + }, + "4": { + "baseColor": { + "value": "#cb4b16", + "type": "color" + }, + "cursorColor": { + "value": "#cb4b16", + "type": "color" + }, + "selectionColor": { + "value": "#cb4b163d", + "type": "color" + }, + "borderColor": { + "value": "#cb4b16cc", + "type": "color" + } + }, + "5": { + "baseColor": { + "value": "#6c71c4", + "type": "color" + }, + "cursorColor": { + "value": "#6c71c4", + "type": "color" + }, + "selectionColor": { + "value": "#6c71c43d", + "type": "color" + }, + "borderColor": { + "value": "#6c71c4cc", + "type": "color" + } + }, + "6": { + "baseColor": { + "value": "#2aa198", + "type": "color" + }, + "cursorColor": { + "value": "#2aa198", + "type": "color" + }, + "selectionColor": { + "value": "#2aa1983d", + "type": "color" + }, + "borderColor": { + "value": "#2aa198cc", + "type": "color" + } + }, + "7": { + "baseColor": { + "value": "#dc322f", + "type": "color" + }, + "cursorColor": { + "value": "#dc322f", + "type": "color" + }, + "selectionColor": { + "value": "#dc322f3d", + "type": "color" + }, + "borderColor": { + "value": "#dc322fcc", + "type": "color" + } + }, + "8": { + "baseColor": { + "value": "#b58900", + "type": "color" + }, + "cursorColor": { + "value": "#b58900", + "type": "color" + }, + "selectionColor": { + "value": "#b589003d", + "type": "color" + }, + "borderColor": { + "value": "#b58900cc", + "type": "color" + } + } + }, + "shadowAlpha": { + "value": 0.32, + "type": "number" + } +} \ No newline at end of file diff --git a/styles/src/buildThemes.ts b/styles/src/buildThemes.ts index 0e8d90d96a00e63a83ce11e0897ee6fec3119a86..2f2d35dcf1c92682d2dfaba6e28a2a64e066e5fa 100644 --- a/styles/src/buildThemes.ts +++ b/styles/src/buildThemes.ts @@ -1,11 +1,20 @@ import * as fs from "fs"; import * as path from "path"; import app from "./styleTree/app"; +import { dark as caveDark, light as caveLight } from "./themes/cave"; import dark from "./themes/dark"; import light from "./themes/light"; +import { dark as solarizedDark, light as solarizedLight } from "./themes/solarized"; +import { dark as sulphurpoolDark, light as sulphurpoolLight } from "./themes/sulphurpool"; import snakeCase from "./utils/snakeCase"; -const themes = [dark, light]; +const themes = [ + dark, light, + caveDark, caveLight, + solarizedDark, solarizedLight, + sulphurpoolDark, sulphurpoolLight +]; + for (let theme of themes) { let styleTree = snakeCase(app(theme)); let styleTreeJSON = JSON.stringify(styleTree, null, 2); diff --git a/styles/src/styleTree/editor.ts b/styles/src/styleTree/editor.ts index db7ebd63f74e5b230656d227f6070a99f9dd1eb5..88e630b357f87c93b064f630671be227476295e0 100644 --- a/styles/src/styleTree/editor.ts +++ b/styles/src/styleTree/editor.ts @@ -37,8 +37,18 @@ export default function editor(theme: Theme) { }; } + const syntax: any = {}; + for (const syntaxKey in theme.syntax) { + const style = theme.syntax[syntaxKey]; + syntax[syntaxKey] = { + color: style.color.value, + weight: style.weight.value, + underline: style.underline, + italic: style.italic, + }; + } + return { - // textColor: theme.syntax.primary.color, textColor: theme.syntax.primary.color.value, background: backgroundColor(theme, 500), activeLineBackground: theme.editor.line.active.value, @@ -125,22 +135,6 @@ export default function editor(theme: Theme) { invalidHintDiagnostic: diagnostic(theme, "muted"), invalidInformationDiagnostic: diagnostic(theme, "muted"), invalidWarningDiagnostic: diagnostic(theme, "muted"), - syntax: { - keyword: theme.syntax.keyword.color.value, - function: theme.syntax.function.color.value, - string: theme.syntax.string.color.value, - type: theme.syntax.type.color.value, - number: theme.syntax.number.color.value, - comment: theme.syntax.comment.color.value, - property: theme.syntax.property.color.value, - variant: theme.syntax.variant.color.value, - constant: theme.syntax.constant.color.value, - title: { color: theme.syntax.title.color.value, weight: "bold" }, - emphasis: theme.textColor.feature.value, - "emphasis.strong": { color: theme.textColor.feature.value, weight: "bold" }, - link_uri: { color: theme.syntax.linkUrl.color.value, underline: true }, - link_text: { color: theme.syntax.linkText.color.value, italic: true }, - list_marker: theme.syntax.punctuation.color.value, - }, + syntax, }; } diff --git a/styles/src/styleTree/selectorModal.ts b/styles/src/styleTree/selectorModal.ts index b4dce880a7a1775f6b3cb6ba0479f86fb9829f43..8966de9faebd3101d85b053ddf4f9a767097ee25 100644 --- a/styles/src/styleTree/selectorModal.ts +++ b/styles/src/styleTree/selectorModal.ts @@ -50,10 +50,6 @@ export default function selectorModal(theme: Theme): Object { top: 7, }, }, - margin: { - bottom: 52, - top: 52, - }, shadow: shadow(theme), }; } diff --git a/styles/src/styleTree/workspace.ts b/styles/src/styleTree/workspace.ts index 57de2f01f4e829b9ea918efc4922dcde980f19f7..609639c467028dc8adeca0485f4c2f6571e74a21 100644 --- a/styles/src/styleTree/workspace.ts +++ b/styles/src/styleTree/workspace.ts @@ -68,6 +68,10 @@ export default function workspace(theme: Theme) { }, }, }; + const shareIcon = { + margin: { top: 3, bottom: 2 }, + cornerRadius: 6, + }; return { background: backgroundColor(theme, 300), @@ -75,6 +79,13 @@ export default function workspace(theme: Theme) { leaderBorderWidth: 2.0, tab, activeTab, + modal: { + margin: { + bottom: 52, + top: 52, + }, + cursor: "Arrow" + }, leftSidebar: { ...sidebar, border: border(theme, "primary", { right: true }), @@ -105,8 +116,9 @@ export default function workspace(theme: Theme) { avatarWidth: 18, height: 32, background: backgroundColor(theme, 100), - shareIconColor: iconColor(theme, "secondary"), - shareIconActiveColor: iconColor(theme, "feature"), + padding: { + left: 80, + }, title: text(theme, "sans", "primary"), avatar: { cornerRadius: 10, @@ -134,9 +146,29 @@ export default function workspace(theme: Theme) { right: 4, }, }, + shareIcon: { + ...shareIcon, + color: iconColor(theme, "secondary") + }, + hoveredShareIcon: { + ...shareIcon, + background: backgroundColor(theme, 100, "hovered"), + color: iconColor(theme, "secondary"), + }, + hoveredActiveShareIcon: { + ...shareIcon, + background: backgroundColor(theme, 100, "hovered"), + color: iconColor(theme, "active"), + }, + activeShareIcon: { + ...shareIcon, + background: backgroundColor(theme, 100, "active"), + color: iconColor(theme, "active"), + }, outdatedWarning: { ...text(theme, "sans", "warning"), size: 13, + margin: { right: 6 } }, }, toolbar: { diff --git a/styles/src/themes/base16.ts b/styles/src/themes/base16.ts new file mode 100644 index 0000000000000000000000000000000000000000..a472837dbe07ac2a245708efc0cca523a79463c7 --- /dev/null +++ b/styles/src/themes/base16.ts @@ -0,0 +1,242 @@ +import { ColorToken, fontWeights, NumberToken } from "../tokens"; +import { withOpacity } from "../utils/color"; +import Theme, { buildPlayer, Syntax } from "./theme"; + +export interface Accents { + "red": ColorToken, + "orange": ColorToken, + "yellow": ColorToken, + "green": ColorToken, + "cyan": ColorToken, + "blue": ColorToken, + "violet": ColorToken, + "magenta": ColorToken, +} + +export function createTheme(name: string, isLight: boolean, neutral: ColorToken[], accent: Accents): Theme { + if (isLight) { + neutral = [...neutral].reverse(); + } + let blend = isLight ? 0.12 : 0.32; + + const backgroundColor = { + 100: { + base: neutral[1], + hovered: withOpacity(neutral[2], blend), + active: withOpacity(neutral[2], blend * 1.5), + focused: neutral[2], + }, + 300: { + base: neutral[1], + hovered: withOpacity(neutral[2], blend), + active: withOpacity(neutral[2], blend * 1.5), + focused: neutral[2], + }, + 500: { + base: neutral[0], + hovered: neutral[1], + active: neutral[1], + focused: neutral[1], + }, + on300: { + base: neutral[0], + hovered: neutral[1], + active: neutral[1], + focused: neutral[1], + }, + on500: { + base: neutral[1], + hovered: neutral[3], + active: neutral[3], + focused: neutral[3], + }, + ok: { + base: accent.green, + hovered: accent.green, + active: accent.green, + focused: accent.green, + }, + error: { + base: accent.red, + hovered: accent.red, + active: accent.red, + focused: accent.red, + }, + warning: { + base: accent.yellow, + hovered: accent.yellow, + active: accent.yellow, + focused: accent.yellow, + }, + info: { + base: accent.blue, + hovered: accent.blue, + active: accent.blue, + focused: accent.blue, + }, + }; + + const borderColor = { + primary: neutral[0], + secondary: neutral[1], + muted: neutral[3], + focused: neutral[3], + active: neutral[3], + ok: accent.green, + error: accent.red, + warning: accent.yellow, + info: accent.blue, + }; + + const textColor = { + primary: neutral[6], + secondary: neutral[5], + muted: neutral[5], + placeholder: neutral[4], + active: neutral[7], + feature: accent.blue, + ok: accent.green, + error: accent.red, + warning: accent.yellow, + info: accent.blue, + }; + + const player = { + 1: buildPlayer(accent.blue), + 2: buildPlayer(accent.green), + 3: buildPlayer(accent.magenta), + 4: buildPlayer(accent.orange), + 5: buildPlayer(accent.violet), + 6: buildPlayer(accent.cyan), + 7: buildPlayer(accent.red), + 8: buildPlayer(accent.yellow), + }; + + const editor = { + background: backgroundColor[500].base, + indent_guide: borderColor.muted, + indent_guide_active: borderColor.secondary, + line: { + active: withOpacity(neutral[7], 0.07), + highlighted: withOpacity(neutral[7], 0.12), + inserted: backgroundColor.ok.active, + deleted: backgroundColor.error.active, + modified: backgroundColor.info.active, + }, + highlight: { + selection: player[1].selectionColor, + occurrence: withOpacity(neutral[0], 0.12), + activeOccurrence: withOpacity(neutral[0], 0.16), + matchingBracket: backgroundColor[500].active, + match: withOpacity(accent.violet, 0.5), + activeMatch: withOpacity(accent.violet, 0.7), + related: backgroundColor[500].focused, + }, + gutter: { + primary: textColor.placeholder, + active: textColor.active, + }, + }; + + const syntax: Syntax = { + primary: { + color: neutral[7], + weight: fontWeights.normal, + }, + comment: { + color: neutral[5], + weight: fontWeights.normal, + }, + punctuation: { + color: neutral[5], + weight: fontWeights.normal, + }, + constant: { + color: neutral[4], + weight: fontWeights.normal, + }, + keyword: { + color: accent.blue, + weight: fontWeights.normal, + }, + function: { + color: accent.yellow, + weight: fontWeights.normal, + }, + type: { + color: accent.cyan, + weight: fontWeights.normal, + }, + variant: { + color: accent.blue, + weight: fontWeights.normal, + }, + property: { + color: accent.blue, + weight: fontWeights.normal, + }, + enum: { + color: accent.orange, + weight: fontWeights.normal, + }, + operator: { + color: accent.orange, + weight: fontWeights.normal, + }, + string: { + color: accent.orange, + weight: fontWeights.normal, + }, + number: { + color: accent.green, + weight: fontWeights.normal, + }, + boolean: { + color: accent.green, + weight: fontWeights.normal, + }, + predictive: { + color: textColor.muted, + weight: fontWeights.normal, + }, + title: { + color: accent.yellow, + weight: fontWeights.bold, + }, + emphasis: { + color: textColor.feature, + weight: fontWeights.normal, + }, + "emphasis.strong": { + color: textColor.feature, + weight: fontWeights.bold, + }, + linkUri: { + color: accent.green, + weight: fontWeights.normal, + underline: true, + }, + linkText: { + color: accent.orange, + weight: fontWeights.normal, + italic: true, + }, + }; + + const shadowAlpha: NumberToken = { + value: blend, + type: "number", + }; + + return { + name, + backgroundColor, + borderColor, + textColor, + iconColor: textColor, + editor, + syntax, + player, + shadowAlpha, + }; +} \ No newline at end of file diff --git a/styles/src/themes/cave.ts b/styles/src/themes/cave.ts new file mode 100644 index 0000000000000000000000000000000000000000..681285dd12f923824f69d0260ba4ab0cb07f7e77 --- /dev/null +++ b/styles/src/themes/cave.ts @@ -0,0 +1,29 @@ +import { createTheme } from "./base16"; +import { color } from "../tokens"; + +const name = "cave"; + +const neutrals = [ + color("#19171c"), + color("#26232a"), + color("#585260"), + color("#655f6d"), + color("#7e7887"), + color("#8b8792"), + color("#e2dfe7"), + color("#efecf4"), +]; + +const colors = { + "red": color("#be4678"), + "orange": color("#aa573c"), + "yellow": color("#a06e3b"), + "green": color("#2a9292"), + "cyan": color("#398bc6"), + "blue": color("#576ddb"), + "violet": color("#955ae7"), + "magenta": color("#bf40bf"), +}; + +export const dark = createTheme(`${name}-dark`, false, neutrals, colors); +export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file diff --git a/styles/src/themes/dark.ts b/styles/src/themes/dark.ts index f7407699dd27bf22456e86e3f03efdbe20f511c0..564ac685ae83ab72bb52c3e9426f56d611e31952 100644 --- a/styles/src/themes/dark.ts +++ b/styles/src/themes/dark.ts @@ -1,4 +1,4 @@ -import { colors, fontWeights, NumberToken } from "../tokens"; +import { color, colors, fontWeights, NumberToken } from "../tokens"; import { withOpacity } from "../utils/color"; import Theme, { buildPlayer, Syntax } from "./theme"; @@ -202,22 +202,22 @@ const syntax: Syntax = { weight: fontWeights.bold, }, emphasis: { - color: textColor.active, + color: textColor.feature, weight: fontWeights.normal, }, - emphasisStrong: { - color: textColor.active, + "emphasis.strong": { + color: textColor.feature, weight: fontWeights.bold, }, - linkUrl: { + linkUri: { color: colors.lime[500], weight: fontWeights.normal, - // TODO: add underline + underline: true, }, linkText: { color: colors.orange[500], weight: fontWeights.normal, - // TODO: add italic + italic: true, }, }; diff --git a/styles/src/themes/light.ts b/styles/src/themes/light.ts index 397c16534104f3b53eb7c47c4737de251b1813de..710754abc58a5c80f4d39330d6e1e1fcd57ead7a 100644 --- a/styles/src/themes/light.ts +++ b/styles/src/themes/light.ts @@ -200,22 +200,22 @@ const syntax: Syntax = { weight: fontWeights.bold, }, emphasis: { - color: textColor.active, + color: textColor.feature, weight: fontWeights.normal, }, - emphasisStrong: { - color: textColor.active, + "emphasis.strong": { + color: textColor.feature, weight: fontWeights.bold, }, - linkUrl: { + linkUri: { color: colors.lime[500], weight: fontWeights.normal, - // TODO: add underline + underline: true }, linkText: { color: colors.red[500], weight: fontWeights.normal, - // TODO: add italic + italic: true }, }; diff --git a/styles/src/themes/solarized.ts b/styles/src/themes/solarized.ts new file mode 100644 index 0000000000000000000000000000000000000000..6116c83d170c47c0aef53fe4e78c95959b37a195 --- /dev/null +++ b/styles/src/themes/solarized.ts @@ -0,0 +1,29 @@ +import { createTheme } from "./base16"; +import { color } from "../tokens"; + +const name = "solarized"; + +const neutrals = [ + color("#002b36"), + color("#073642"), + color("#586e75"), + color("#657b83"), + color("#839496"), + color("#93a1a1"), + color("#eee8d5"), + color("#fdf6e3"), +]; + +const colors = { + "red": color("#dc322f"), + "orange": color("#cb4b16"), + "yellow": color("#b58900"), + "green": color("#859900"), + "cyan": color("#2aa198"), + "blue": color("#268bd2"), + "violet": color("#6c71c4"), + "magenta": color("#d33682"), +}; + +export const dark = createTheme(`${name}-dark`, false, neutrals, colors); +export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file diff --git a/styles/src/themes/sulphurpool.ts b/styles/src/themes/sulphurpool.ts new file mode 100644 index 0000000000000000000000000000000000000000..01e7c419f1f8e01fc648de4a892dc1334c3be092 --- /dev/null +++ b/styles/src/themes/sulphurpool.ts @@ -0,0 +1,29 @@ +import { createTheme } from "./base16"; +import { color } from "../tokens"; + +const name = "sulphurpool"; + +const neutrals = [ + color("#202746"), + color("#293256"), + color("#5e6687"), + color("#6b7394"), + color("#898ea4"), + color("#979db4"), + color("#dfe2f1"), + color("#f5f7ff"), +] + +const colors = { + "red": color("#c94922"), + "orange": color("#c76b29"), + "yellow": color("#c08b30"), + "green": color("#ac9739"), + "cyan": color("#22a2c9"), + "blue": color("#3d8fd1"), + "violet": color("#6679cc"), + "magenta": color("#9c637a"), +}; + +export const dark = createTheme(`${name}-dark`, false, neutrals, colors); +export const light = createTheme(`${name}-light`, true, neutrals, colors); \ No newline at end of file diff --git a/styles/src/themes/theme.ts b/styles/src/themes/theme.ts index f4b3bcc6808082efb3cac6877eb4421fcb7ddfd8..aa422e03306a089b093ec0efec872ea829187767 100644 --- a/styles/src/themes/theme.ts +++ b/styles/src/themes/theme.ts @@ -3,7 +3,9 @@ import { withOpacity } from "../utils/color"; export interface SyntaxHighlightStyle { color: ColorToken; - weight: FontWeightToken; + weight?: FontWeightToken; + underline?: boolean, + italic?: boolean, } export interface Player { @@ -49,21 +51,30 @@ export interface Syntax { number: SyntaxHighlightStyle; boolean: SyntaxHighlightStyle; predictive: SyntaxHighlightStyle; - // TODO: Either move the following or rename title: SyntaxHighlightStyle; emphasis: SyntaxHighlightStyle; - emphasisStrong: SyntaxHighlightStyle; - linkUrl: SyntaxHighlightStyle; + linkUri: SyntaxHighlightStyle; linkText: SyntaxHighlightStyle; + + [key: string]: SyntaxHighlightStyle; }; export default interface Theme { name: string; backgroundColor: { + // Basically just Title Bar + // Lowest background level 100: BackgroundColorSet; + // Tab bars, panels, popovers + // Mid-ground 300: BackgroundColorSet; + // The editor + // Foreground 500: BackgroundColorSet; + // Hacks for elements on top of the midground + // Buttons in a panel, tab bar, or panel on300: BackgroundColorSet; + // Hacks for elements on top of the editor on500: BackgroundColorSet; ok: BackgroundColorSet; error: BackgroundColorSet; diff --git a/styles/src/tokens.ts b/styles/src/tokens.ts index 5e412ae042aedda1ca9ac11c47aebddbd8ab9d71..4e97d8ea792fc5501035a71831977d37bb64426a 100644 --- a/styles/src/tokens.ts +++ b/styles/src/tokens.ts @@ -71,6 +71,12 @@ export interface ColorToken { type: "color", step?: number, } +export function color(value: string): ColorToken { + return { + value, + type: "color", + }; +} export const colors = { neutral: colorRamp(["white", "black"], { steps: 37, increment: 25 }), // (900/25) + 1 rose: colorRamp("#F43F5EFF"), diff --git a/styles/src/utils/snakeCase.ts b/styles/src/utils/snakeCase.ts index 890017f1c6cee0e169b7afb663d46b3720fbb15e..85a038c663968b07ae4a108164226c7c141a270d 100644 --- a/styles/src/utils/snakeCase.ts +++ b/styles/src/utils/snakeCase.ts @@ -17,7 +17,7 @@ type SnakeCased = { export default function snakeCaseTree(object: T): SnakeCased { const snakeObject: any = {}; for (const key in object) { - snakeObject[snakeCase(key)] = snakeCaseValue(object[key]); + snakeObject[snakeCase(key, { keepSpecialCharacters: true })] = snakeCaseValue(object[key]); } return snakeObject; }