diff --git a/docs/source/users/index.md b/docs/source/users/index.md index 164edf735..75dbf7efc 100644 --- a/docs/source/users/index.md +++ b/docs/source/users/index.md @@ -171,7 +171,7 @@ Once you have set all the necessary keys, click the "back" (left arrow) button i alt="Screen shot of the initial, blank, chat interface." class="screenshot" /> -To compose a message, type it in the text box at the bottom of the chat interface and press SHIFT+ENTER to send. You can press ENTER to add a new line. Once you have sent a message, you should see a response from Jupyternaut, the Jupyter AI chatbot. +To compose a message, type it in the text box at the bottom of the chat interface and press ENTER to send it. You can press SHIFT+ENTER to add a new line. (These are the default keybindings; you can change them in the chat settings pane.) Once you have sent a message, you should see a response from Jupyternaut, the Jupyter AI chatbot. Screen shot of an example "Hello world" message sent to Jupyternaut, who responds with "Hello world, how are you today?"SHIFT+ENTER to send your message. Your outgoing message will include your selection. +After highlighting a portion of your notebook, check "Include selection" in the chat panel, type your message, and then send your message. Your outgoing message will include your selection. Screen shot of JupyterLab with Jupyter AI's chat panel active. A Python function is selected, the user has "What does this code do?" as their prompt, and the user has chosen to include the selection with their message. unknown; replaceSelection: boolean; toggleReplaceSelection: () => unknown; - helperText: JSX.Element + sendWithShiftEnter: boolean; sx?: SxProps; }; export function ChatInput(props: ChatInputProps): JSX.Element { function handleKeyDown(event: React.KeyboardEvent) { - if (event.key === 'Enter' && event.shiftKey) { + if (event.key === 'Enter' && ( + (props.sendWithShiftEnter && event.shiftKey) + || (!props.sendWithShiftEnter && !event.shiftKey) + )) { props.onSend(); event.stopPropagation(); event.preventDefault(); } } + + // Set the helper text based on whether Shift+Enter is used for sending. + const helperText = props.sendWithShiftEnter + ? Press Shift+Enter to send message + : Press Shift+Enter to add a new line; + return ( @@ -64,7 +73,7 @@ export function ChatInput(props: ChatInputProps): JSX.Element { FormHelperTextProps={{ sx: {marginLeft: 'auto', marginRight: 0} }} - helperText={props.value.length > 2 ? props.helperText : ' '} + helperText={props.value.length > 2 ? helperText : ' '} /> {props.hasSelection && ( diff --git a/packages/jupyter-ai/src/components/chat-settings.tsx b/packages/jupyter-ai/src/components/chat-settings.tsx index d36a3bf63..02351dba5 100644 --- a/packages/jupyter-ai/src/components/chat-settings.tsx +++ b/packages/jupyter-ai/src/components/chat-settings.tsx @@ -3,7 +3,12 @@ import { Box } from '@mui/system'; import { Alert, Button, + FormControl, + FormControlLabel, + FormLabel, MenuItem, + Radio, + RadioGroup, TextField, CircularProgress } from '@mui/material'; @@ -42,7 +47,8 @@ export function ChatSettings() { const [inputConfig, setInputConfig] = useState({ model_provider_id: null, embeddings_provider_id: null, - api_keys: {} + api_keys: {}, + send_with_shift_enter: null }); // whether the form is currently saving @@ -109,7 +115,8 @@ export function ChatSettings() { const handleSave = async () => { const inputConfigCopy: AiService.Config = { ...inputConfig, - api_keys: { ...inputConfig.api_keys } + api_keys: { ...inputConfig.api_keys }, + send_with_shift_enter: inputConfig.send_with_shift_enter ?? true }; // delete any empty api keys @@ -256,6 +263,38 @@ export function ChatSettings() { /> ) )} + + + When writing a message, press Enter to: + + + setInputConfig(inputConfig => { + return ({ + ...inputConfig, + send_with_shift_enter: (e.target as HTMLInputElement).value === 'newline' + }); + })} + > + } + label="Send the message" + /> + } + label={ + <>Start a new line (use Shift+Enter to send) + } + /> + +