Compare commits

..

2 Commits

Author SHA1 Message Date
Mikayla Maki
a46eb6737c make it remove old paths 2025-09-03 21:55:09 -07:00
Mikayla Maki
d80fa82009 Write to the user settings file when changing language with the selector 2025-09-03 21:43:47 -07:00
9 changed files with 82 additions and 50 deletions

View File

@@ -83,7 +83,6 @@ struct EditFileToolPartialInput {
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
#[schemars(inline)]
pub enum EditFileMode {
Edit,
Create,

View File

@@ -11,7 +11,6 @@ use crate::{AgentTool, ToolCallEventStream};
#[derive(Debug, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "snake_case")]
#[schemars(inline)]
pub enum Timezone {
/// Use UTC for the datetime.
Utc,

View File

@@ -96,7 +96,7 @@ impl Model {
pub fn max_token_count(&self) -> u64 {
match self {
Self::Chat | Self::Reasoner => 128_000,
Self::Chat | Self::Reasoner => 64_000,
Self::Custom { max_tokens, .. } => *max_tokens,
}
}
@@ -104,7 +104,7 @@ impl Model {
pub fn max_output_tokens(&self) -> Option<u64> {
match self {
Self::Chat => Some(8_192),
Self::Reasoner => Some(64_000),
Self::Reasoner => Some(8_192),
Self::Custom {
max_output_tokens, ..
} => *max_output_tokens,

View File

@@ -149,6 +149,11 @@ struct GlobalFs(Arc<dyn Fs>);
impl Global for GlobalFs {}
impl dyn Fs {
pub fn try_global(cx: &App) -> Option<Arc<Self>> {
cx.try_global::<GlobalFs>()
.map(|global_fs| global_fs.0.clone())
}
/// Returns the global [`Fs`].
pub fn global(cx: &App) -> Arc<Self> {
GlobalFs::global(cx).0.clone()

View File

@@ -552,7 +552,7 @@ impl DispatchTree {
let mut current_node_id = Some(target);
while let Some(node_id) = current_node_id {
dispatch_path.push(node_id);
current_node_id = self.nodes.get(node_id.0).and_then(|node| node.parent);
current_node_id = self.nodes[node_id.0].parent;
}
dispatch_path.reverse(); // Reverse the path so it goes from the root to the focused node.
dispatch_path

View File

@@ -10,9 +10,11 @@ use gpui::{
App, Context, DismissEvent, Entity, EventEmitter, FocusHandle, Focusable, ParentElement,
Render, Styled, WeakEntity, Window, actions,
};
use language::{Buffer, LanguageMatcher, LanguageName, LanguageRegistry};
use language::{
Buffer, LanguageMatcher, LanguageName, LanguageRegistry, language_settings::AllLanguageSettings,
};
use picker::{Picker, PickerDelegate};
use project::Project;
use project::{Fs, Project, ProjectItem};
use settings::Settings;
use std::{ops::Not as _, path::Path, sync::Arc};
use ui::{HighlightedLabel, ListItem, ListItemSpacing, prelude::*};
@@ -195,8 +197,8 @@ impl PickerDelegate for LanguageSelectorDelegate {
fn confirm(&mut self, _: bool, window: &mut Window, cx: &mut Context<Picker<Self>>) {
if let Some(mat) = self.matches.get(self.selected_index) {
let language_name = &self.candidates[mat.candidate_id].string;
let language = self.language_registry.language_for_name(language_name);
let language_name = self.candidates[mat.candidate_id].string.clone();
let language = self.language_registry.language_for_name(&language_name);
let project = self.project.downgrade();
let buffer = self.buffer.downgrade();
cx.spawn_in(window, async move |_, cx| {
@@ -205,6 +207,35 @@ impl PickerDelegate for LanguageSelectorDelegate {
let buffer = buffer.upgrade().context("buffer was dropped")?;
project.update(cx, |project, cx| {
project.set_language_for_buffer(&buffer, language, cx);
let absolute_path = buffer
.read(cx)
.project_path(cx)
.and_then(|path| project.absolute_path(&path, cx));
if let Some(absolute_path) = absolute_path {
let absolute_path = absolute_path.to_string_lossy().to_string();
if let Some(fs) = <dyn Fs>::try_global(cx) {
settings::update_settings_file::<AllLanguageSettings>(
fs,
cx,
move |language_settings, _| {
for paths in language_settings.file_types.values_mut() {
if let Some(ix) =
paths.iter().position(|path| path == &absolute_path)
{
paths.swap_remove(ix);
}
}
language_settings
.file_types
.entry(Arc::from(language_name.as_str()))
.or_default()
.push(absolute_path);
},
);
}
}
})
})
.detach_and_log_err(cx);

View File

@@ -34,7 +34,7 @@ use workspace::Workspace;
use std::mem;
use std::{fmt::Debug, ops::RangeInclusive, rc::Rc};
use crate::{BlockContext, BlockProperties, ContentMode, ImeState, TerminalMode, TerminalView};
use crate::{BlockContext, BlockProperties, ContentMode, TerminalMode, TerminalView};
/// The information generated during layout that is necessary for painting.
pub struct LayoutState {
@@ -1191,7 +1191,10 @@ impl Element for TerminalElement {
let origin =
bounds.origin + Point::new(layout.gutter, px(0.)) - Point::new(px(0.), scroll_top);
let marked_text = self.terminal_view.read(cx).ime_state.as_ref().map(|ime_state| ime_state.marked_text.clone());
let marked_text_cloned: Option<String> = {
let ime_state = self.terminal_view.read(cx);
ime_state.marked_text.clone()
};
let terminal_input_handler = TerminalInputHandler {
terminal: self.terminal.clone(),
@@ -1277,7 +1280,7 @@ impl Element for TerminalElement {
}
let text_paint_time = text_paint_start.elapsed();
if let Some(text_to_mark) = &marked_text
if let Some(text_to_mark) = &marked_text_cloned
&& !text_to_mark.is_empty()
&& let Some(cursor_layout) = &original_cursor {
let ime_position = cursor_layout.bounding_rect(origin).origin;
@@ -1306,7 +1309,7 @@ impl Element for TerminalElement {
.log_err();
}
if self.cursor_visible && marked_text.is_none()
if self.cursor_visible && marked_text_cloned.is_none()
&& let Some(mut cursor) = original_cursor {
cursor.paint(origin, window, cx);
}
@@ -1414,13 +1417,15 @@ impl InputHandler for TerminalInputHandler {
&mut self,
_range_utf16: Option<std::ops::Range<usize>>,
new_text: &str,
new_selected_range: Option<std::ops::Range<usize>>,
new_marked_range: Option<std::ops::Range<usize>>,
_window: &mut Window,
cx: &mut App,
) {
self.terminal_view.update(cx, |view, view_cx| {
view.set_marked_text(new_text.to_string(), new_selected_range, view_cx);
});
if let Some(range) = new_marked_range {
self.terminal_view.update(cx, |view, view_cx| {
view.set_marked_text(new_text.to_string(), range, view_cx);
});
}
}
fn unmark_text(&mut self, _window: &mut Window, cx: &mut App) {

View File

@@ -62,11 +62,6 @@ use std::{
time::Duration,
};
pub struct ImeState {
pub marked_text: String,
pub marked_range_utf16: Option<Range<usize>>,
}
const CURSOR_BLINK_INTERVAL: Duration = Duration::from_millis(500);
const TERMINAL_SCROLLBAR_WIDTH: Pixels = px(12.);
@@ -143,7 +138,8 @@ pub struct TerminalView {
scroll_handle: TerminalScrollHandle,
show_scrollbar: bool,
hide_scrollbar_task: Option<Task<()>>,
ime_state: Option<ImeState>,
marked_text: Option<String>,
marked_range_utf16: Option<Range<usize>>,
_subscriptions: Vec<Subscription>,
_terminal_subscriptions: Vec<Subscription>,
}
@@ -267,7 +263,8 @@ impl TerminalView {
show_scrollbar: !Self::should_autohide_scrollbar(cx),
hide_scrollbar_task: None,
cwd_serialized: false,
ime_state: None,
marked_text: None,
marked_range_utf16: None,
_subscriptions: vec![
focus_in,
focus_out,
@@ -326,25 +323,24 @@ impl TerminalView {
pub(crate) fn set_marked_text(
&mut self,
text: String,
range: Option<Range<usize>>,
range: Range<usize>,
cx: &mut Context<Self>,
) {
self.ime_state = Some(ImeState {
marked_text: text,
marked_range_utf16: range,
});
self.marked_text = Some(text);
self.marked_range_utf16 = Some(range);
cx.notify();
}
/// Gets the current marked range (UTF-16).
pub(crate) fn marked_text_range(&self) -> Option<Range<usize>> {
self.ime_state.as_ref()?.marked_range_utf16.clone()
self.marked_range_utf16.clone()
}
/// Clears the marked (pre-edit) text state.
pub(crate) fn clear_marked_text(&mut self, cx: &mut Context<Self>) {
if self.ime_state.is_some() {
self.ime_state = None;
if self.marked_text.is_some() {
self.marked_text = None;
self.marked_range_utf16 = None;
cx.notify();
}
}

View File

@@ -435,24 +435,21 @@ To do it via your `settings.json`, add the following snippet under `language_mod
```json
{
"language_models": {
"openai_compatible": {
// Using Together AI as an example
"Together AI": {
"api_url": "https://api.together.xyz/v1",
"available_models": [
{
"name": "mistralai/Mixtral-8x7B-Instruct-v0.1",
"display_name": "Together Mixtral 8x7B",
"max_tokens": 32768,
"capabilities": {
"tools": true,
"images": false,
"parallel_tool_calls": false,
"prompt_cache_key": false
}
"openai": {
"api_url": "https://api.together.xyz/v1", // Using Together AI as an example
"available_models": [
{
"name": "mistralai/Mixtral-8x7B-Instruct-v0.1",
"display_name": "Together Mixtral 8x7B",
"max_tokens": 32768,
"capabilities": {
"tools": true,
"images": false,
"parallel_tool_calls": false,
"prompt_cache_key": false
}
]
}
}
]
}
}
}
@@ -466,7 +463,7 @@ By default, OpenAI-compatible models inherit the following capabilities:
- `prompt_cache_key`: false (does not support `prompt_cache_key` parameter)
Note that LLM API keys aren't stored in your settings file.
So, ensure you have it set in your environment variables (`<PROVIDER_NAME>_API_KEY=<your api key>`) so your settings can pick it up. In the example above, it would be `TOGETHER_AI_API_KEY=<your api key>`.
So, ensure you have it set in your environment variables (`OPENAI_API_KEY=<your api key>`) so your settings can pick it up.
### OpenRouter {#openrouter}