Compare commits
2 Commits
improve-te
...
make-langu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a46eb6737c | ||
|
|
d80fa82009 |
@@ -83,7 +83,6 @@ struct EditFileToolPartialInput {
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
#[schemars(inline)]
|
||||
pub enum EditFileMode {
|
||||
Edit,
|
||||
Create,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user