ollama_chat 0.0.71 → 0.0.72

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +28 -0
  3. data/README.md +42 -40
  4. data/lib/ollama_chat/chat.rb +105 -63
  5. data/lib/ollama_chat/clipboard.rb +32 -6
  6. data/lib/ollama_chat/config_handling.rb +18 -6
  7. data/lib/ollama_chat/file_editing.rb +61 -0
  8. data/lib/ollama_chat/information.rb +42 -40
  9. data/lib/ollama_chat/input_content.rb +3 -9
  10. data/lib/ollama_chat/message_editing.rb +1 -9
  11. data/lib/ollama_chat/message_list.rb +3 -30
  12. data/lib/ollama_chat/ollama_chat_config/default_config.yml +34 -0
  13. data/lib/ollama_chat/pager.rb +40 -0
  14. data/lib/ollama_chat/personae_management.rb +296 -0
  15. data/lib/ollama_chat/redis_cache.rb +2 -2
  16. data/lib/ollama_chat/tool_calling.rb +4 -3
  17. data/lib/ollama_chat/tools/copy_to_clipboard.rb +21 -5
  18. data/lib/ollama_chat/tools/execute_grep.rb +1 -1
  19. data/lib/ollama_chat/tools/generate_password.rb +3 -3
  20. data/lib/ollama_chat/tools/get_time.rb +55 -59
  21. data/lib/ollama_chat/tools/insert_into_editor.rb +68 -0
  22. data/lib/ollama_chat/tools/open_file_in_editor.rb +0 -1
  23. data/lib/ollama_chat/tools/run_tests.rb +2 -2
  24. data/lib/ollama_chat/tools/weather/dwd_sensor.rb +2 -2
  25. data/lib/ollama_chat/tools/write_file.rb +5 -2
  26. data/lib/ollama_chat/tools.rb +1 -0
  27. data/lib/ollama_chat/utils/chooser.rb +1 -1
  28. data/lib/ollama_chat/version.rb +1 -1
  29. data/lib/ollama_chat/vim.rb +4 -4
  30. data/lib/ollama_chat.rb +4 -1
  31. data/ollama_chat.gemspec +5 -5
  32. data/spec/ollama_chat/chat_spec.rb +0 -1
  33. data/spec/ollama_chat/clipboard_spec.rb +3 -3
  34. data/spec/ollama_chat/input_content_spec.rb +5 -4
  35. data/spec/ollama_chat/message_editing_spec.rb +4 -3
  36. data/spec/ollama_chat/tools/copy_to_clipboard_spec.rb +39 -7
  37. data/spec/ollama_chat/tools/insert_into_editor_spec.rb +126 -0
  38. data/spec/spec_helper.rb +1 -1
  39. metadata +13 -3
  40. /data/lib/ollama_chat/{env_config.rb → oc.rb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e83451e14cc4c204b237950b58832b231440487cf490e9434ee127654e849e22
4
- data.tar.gz: 8fb94fb04d963e05d778edc13af7c0988f3d7f180ea17af90d51a6d5bf07a74c
3
+ metadata.gz: aba37f4f59280b1d21b76df79cb20b1e6d4f1b7e05fd91dfd6940368ff8a168f
4
+ data.tar.gz: 88d8d50a503c98973159f2874c0f04a4139e27469363c77b66560e0a965cf890
5
5
  SHA512:
6
- metadata.gz: b2cca9e66e8063fd891ffafeac1c32c7a18467056d4b64c04476cb31154be6f23b6fd13ad3b38299c63e73bdaa73813048cf7e89150d398f4dd21de39a4c3d3a
7
- data.tar.gz: cd134c0ff8544014765e792e104c76a47c1511d4f219665364eda23e52c7b6dcd382058d935c54658ef93407a0a697227cc2cef88510b8555c4a294ac4102d9e
6
+ metadata.gz: 9bc913077bc16ded309925188841e5f803521df0582a47c747fd20c31b03b4a15cfdabf324f683a910d3f9de4f2003b8b31867a4da052e84c072736033f613a2
7
+ data.tar.gz: 9df32e077b73b959ddff9754241fe10a507b8b861e917c59dd6a6032ed4eb4d520ce8bf3047d4401f06e528c17de55d2cba12d26137d52b8fc69eeddf0d17045
data/CHANGES.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changes
2
2
 
3
+ ## 2026-03-04 v0.0.72
4
+
5
+ - Introduced `OllamaChat::PersonaeManagement` module and `/persona` command
6
+ with subcommands `add`, `delete`, `edit`, `list`, `play`, `file`, `info`,
7
+ `load`.
8
+ - Added `/config reload` subcommand to `OllamaChat::Chat`; handler
9
+ `reload_config` in `OllamaChat::ConfigHandling` prompts for confirmation,
10
+ calls `save_conversation`, then restarts with `exec($0,*ARGV)`.
11
+ - Added `-p` command‑line option (`-p PERSONA`) to load personas at startup.
12
+ - Created `OllamaChat::Pager` module for pager functionality.
13
+ - Created `OllamaChat::FileEditing` module; refactored `edit_config`,
14
+ `compose`, `revise_last` to use `edit_file`; added `vim(server_name = nil)`
15
+ returning `OllamaChat::Vim` and `perform_insert(text:, content:)`.
16
+ - Added LLM‑driven tool `insert_into_editor`
17
+ (`lib/ollama_chat/tools/insert_into_editor.rb`) with RSpec tests; default
18
+ config (`default_config.yml`) now enables confirmation flag for this tool.
19
+ - Enhanced `copy_to_clipboard` tool: accepts optional `text` parameter,
20
+ includes helper `last_message_content`, returns `true` on success, updated
21
+ error messages, added test for custom text.
22
+ - Added `bytes_written` tracking to `write_file` tool; fixed return hash key.
23
+ - Added visual separator for tool output.
24
+ - Renamed `env_config.rb` to `oc.rb`; updated requires accordingly.
25
+ - Added `save_history` call after conversation backup to persist history before
26
+ restart.
27
+ - Updated documentation and help messages to reflect new commands and options.
28
+ - Standardised type hints across codebase, replacing generic Boolean comments
29
+ with explicit `[ true, false ]`.
30
+
3
31
  ## 2026-02-26 v0.0.71
4
32
 
5
33
  - Add new clipboard utilities: `tools/copy_to_clipboard.rb` and
data/README.md CHANGED
@@ -58,6 +58,7 @@ Usage: ollama_chat [OPTIONS]
58
58
  -u URL the ollama base url, OLLAMA_URL
59
59
  -m MODEL the ollama model to chat with, OLLAMA_CHAT_MODEL, ?selector
60
60
  -s SYSTEM the system prompt to use as a file, OLLAMA_CHAT_SYSTEM, ?selector
61
+ -p PERSONA load a persona via name/file for roleplay at startup
61
62
  -c CHAT a saved chat conversation to load
62
63
  -C COLLECTION name of the collection used in this conversation
63
64
  -D DOCUMENT load document and add to embeddings collection (multiple)
@@ -151,46 +152,47 @@ subject - the young, blue-eyed cat.
151
152
  The following commands can be given inside the chat, if prefixed by a `/`:
152
153
 
153
154
  ```
154
- /reconnect reconnect to current ollama server
155
- /copy to copy last response to clipboard
156
- /paste to paste content
157
- /markdown toggle markdown output
158
- /stream toggle stream output
159
- /location toggle location submission
160
- /voice [change] toggle voice output or change the voice
161
- /last [n] show the last n / 1 system/assistant message
162
- /list [n] list the last n / all conversation exchanges
163
- /clear [what] clear what=messages|links|history|tags|all
164
- /clobber clear the conversation, links, and collection
165
- /drop [n] drop the last n exchanges, defaults to 1
166
- /model change the model
167
- /system [show] change/show system prompt
168
- /prompt prefill user prompt with preset prompts
169
- /regenerate the last answer message
170
- /collection [clear|change] change (default) collection or clear
171
- /info show information for current session
172
- /config output current configuration ("/Users/flori/.config/ollama_chat/config.yml")
173
- /document_policy pick a scan policy for document references
174
- /think choose ollama think mode setting for models
175
- /think_loud enable to think out loud instead of silently
176
- /import source import the source's content
177
- /summarize [n] source summarize the source's content in n words
178
- /embedding toggle embedding paused or not
179
- /embed source embed the source's content
180
- /web [n] query query web & for n(=1) results (policy: importing)
181
- /links [clear] display (or clear) links used in the chat
182
- /save filename store conversation messages
183
- /load filename load conversation messages
184
- /compose compose content using an EDITOR
185
- /input [pattern] select and read content from a file (default: **/*)
186
- /context [pattern...] collect context with glob patterns
187
- /revise_last edit the last response in an external editor
188
- /output filename save last response to filename
189
- /pipe command write last response to command's stdin
190
- /tools [enable|disable|on|off] list enabled, enable/disable tools, support on/off
191
- /vim insert the last message into a vim server
192
- /quit to quit
193
- /help [me] to view this help (me = interactive ai help)
155
+ /reconnect reconnect to current ollama server
156
+ /copy to copy last response to clipboard
157
+ /paste to paste content
158
+ /markdown toggle markdown output
159
+ /stream toggle stream output
160
+ /location toggle location submission
161
+ /voice [change] toggle voice output or change the voice
162
+ /last [n] show the last n / 1 system/assistant message
163
+ /list [n] list the last n / all conversation exchanges
164
+ /clear [what] clear what=messages|links|history|tags|all
165
+ /clobber clear the conversation, links, and collection
166
+ /drop [n] drop the last n exchanges, defaults to 1
167
+ /model change the model
168
+ /system [show] change/show system prompt
169
+ /prompt prefill user prompt with preset prompts
170
+ /persona add|delete|edit|file|info|list|load|play manage and load/play personas for roleplay
171
+ /regenerate the last answer message
172
+ /collection [clear|change] change (default) collection or clear
173
+ /info show information for current session
174
+ /config [edit|reload] output/edit/reload current configuration ("/Users/flori/.config/ollama_chat/config.yml")
175
+ /document_policy pick a scan policy for document references
176
+ /think choose ollama think mode setting for models
177
+ /think_loud enable to think out loud instead of silently
178
+ /import source import the source's content
179
+ /summarize [n] source summarize the source's content in n words
180
+ /embedding toggle embedding paused or not
181
+ /embed source embed the source's content
182
+ /web [n] query query web & for n(=1) results (policy: importing)
183
+ /links [clear] display (or clear) links used in the chat
184
+ /save filename store conversation messages
185
+ /load filename load conversation messages
186
+ /compose compose content using an EDITOR
187
+ /input [pattern] select and read content from a file (default: **/*)
188
+ /context [pattern...] collect context with glob patterns
189
+ /revise_last edit the last response in an external editor
190
+ /output filename save last response to filename
191
+ /pipe command write last response to command's stdin
192
+ /tools [enable|disable|on|off] list enabled, enable/disable tools, support on/off
193
+ /vim insert the last message into a vim server
194
+ /quit to quit
195
+ /help [me] to view this help (me = interactive ai help)
194
196
  ```
195
197
 
196
198
  ### Using `ollama_chat_send` to send input to a running `ollama_chat`
@@ -47,15 +47,18 @@ class OllamaChat::Chat
47
47
  include OllamaChat::MessageOutput
48
48
  include OllamaChat::Clipboard
49
49
  include OllamaChat::MessageFormat
50
+ include OllamaChat::Pager
50
51
  include OllamaChat::History
51
52
  include OllamaChat::ServerSocket
52
53
  include OllamaChat::KramdownANSI
54
+ include OllamaChat::FileEditing
53
55
  include OllamaChat::Conversation
54
56
  include OllamaChat::InputContent
55
57
  include OllamaChat::MessageEditing
56
58
  include OllamaChat::LocationHandling
57
59
  include OllamaChat::ToolCalling
58
60
  include OllamaChat::ConfigHandling
61
+ include OllamaChat::PersonaeManagement
59
62
 
60
63
  # Initializes a new OllamaChat::Chat instance with the given command-line
61
64
  # arguments.
@@ -85,7 +88,7 @@ class OllamaChat::Chat
85
88
  # @raise [RuntimeError] If the Ollama API version is less than 0.9.0, indicating
86
89
  # incompatibility with required API features
87
90
  def initialize(argv: ARGV.dup)
88
- @opts = go 'f:u:m:s:c:C:D:MESVh', argv
91
+ @opts = go 'f:u:m:s:p:c:C:D:MESVh', argv
89
92
  @opts[?h] and exit usage
90
93
  @opts[?V] and exit version
91
94
  @messages = OllamaChat::MessageList.new(self)
@@ -113,6 +116,7 @@ class OllamaChat::Chat
113
116
  @enabled_tools = default_enabled_tools
114
117
  @tool_call_results = {}
115
118
  init_chat_history
119
+ setup_personae_directory
116
120
  @opts[?S] and init_server_socket
117
121
  rescue ComplexConfig::AttributeMissing, ComplexConfig::ConfigurationSyntaxError => e
118
122
  fix_config(e)
@@ -155,38 +159,15 @@ class OllamaChat::Chat
155
159
  # messages associated with this instance
156
160
  attr_reader :messages
157
161
 
158
- # The start method initializes the chat session by displaying information and
159
- # conversation history, then prompts the user for input to begin interacting
160
- # with the chat.
162
+ # The start method initializes the chat session by displaying information,
163
+ # then prompts the user for input to begin interacting with the chat.
161
164
  def start
162
165
  info
163
- if messages.size > 1
164
- messages.list_conversation(2)
165
- end
166
166
  STDOUT.puts "\nType /help to display the chat help."
167
167
 
168
168
  interact_with_user
169
169
  end
170
170
 
171
- # The vim method creates and returns a new Vim instance for interacting with
172
- # a Vim server.
173
- #
174
- # This method initializes a Vim client that can be used to insert text into
175
- # Vim buffers or open files in a running Vim server. It derives the server
176
- # name from the provided argument or uses a default server name based on the
177
- # current working directory.
178
- #
179
- # @param server_name [ String, nil ] the name of the Vim server to connect to
180
- # If nil or empty, a default server name is derived from the current
181
- # working directory
182
- #
183
- # @return [ OllamaChat::Vim ] a new Vim instance configured with the
184
- # specified server name
185
- def vim(server_name = nil)
186
- clientserver = config.vim?&.clientserver
187
- OllamaChat::Vim.new(server_name, clientserver:)
188
- end
189
-
190
171
  # The debug method accesses the debug configuration setting.
191
172
  #
192
173
  # @return [TrueClass, FalseClass] the current debug mode status
@@ -222,6 +203,7 @@ class OllamaChat::Chat
222
203
  copy_to_clipboard
223
204
  :next
224
205
  when %r(^/paste$)
206
+ @parse_content = false
225
207
  paste_from_clipboard
226
208
  when %r(^/markdown$)
227
209
  markdown.toggle
@@ -385,18 +367,73 @@ class OllamaChat::Chat
385
367
  tools_support.set(false, show: true)
386
368
  end
387
369
  :next
388
- when %r(^/config(?:\s+(edit))?$)
370
+ when %r(^/config(?:\s+(edit|reload))?$)
389
371
  case $1
390
372
  when 'edit'
391
373
  edit_config
374
+ when 'reload'
375
+ reload_config
392
376
  else
393
377
  display_config
394
378
  end
395
379
  :next
380
+ when %r(^/persona(?:\s+(add|delete|edit|file|info|list|load|play))?$)
381
+ @parse_content = false
382
+ case $1
383
+ when 'add'
384
+ if result = add_persona
385
+ result
386
+ else
387
+ :next
388
+ end
389
+ when 'delete'
390
+ if result = delete_persona
391
+ result
392
+ else
393
+ :next
394
+ end
395
+ when 'edit'
396
+ if result = edit_persona
397
+ result
398
+ else
399
+ :next
400
+ end
401
+ when 'file'
402
+ if pathname = choose_filename('**/*.md')
403
+ pathname.read
404
+ else
405
+ :next
406
+ end
407
+ when 'info'
408
+ info_persona
409
+ :next
410
+ when 'list'
411
+ list_personae
412
+ :next
413
+ when 'load'
414
+ if result = load_personae
415
+ result
416
+ else
417
+ :next
418
+ end
419
+ when 'play'
420
+ if pathname = choose_filename('**/*.md')
421
+ play_persona_file(pathname)
422
+ else
423
+ :next
424
+ end
425
+ else
426
+ if result = play_persona.full?
427
+ result
428
+ else
429
+ :next
430
+ end
431
+ end
396
432
  when %r(^/quit$), nil
397
433
  STDOUT.puts "Goodbye."
398
434
  :return
399
435
  when %r(^/help me$)
436
+ @parse_content = false
400
437
  config.prompts.help % { commands: display_chat_help_message }
401
438
  when %r(^/)
402
439
  display_chat_help
@@ -563,46 +600,51 @@ class OllamaChat::Chat
563
600
  # interaction.
564
601
  def interact_with_user
565
602
  loop do
566
- @parse_content = true
567
- type = :terminal_input
568
- input_prompt = bold { color(172) { message_type(@images) + " user" } } + bold { "> " }
569
- begin
570
- if content = handle_tool_call_results?
571
- @parse_content = false
572
- else
573
- content = enable_command_completion do
574
- if prefill_prompt = @prefill_prompt.full?
575
- Reline.pre_input_hook = -> {
576
- Reline.insert_text prefill_prompt.gsub(/\n*\z/, '')
577
- @prefill_prompt = nil
578
- }
579
- else
580
- Reline.pre_input_hook = nil
603
+ if persona_result = setup_persona_from_opts
604
+ @parse_content = false
605
+ content = persona_result
606
+ else
607
+ @parse_content = true
608
+ type = :terminal_input
609
+ input_prompt = bold { color(172) { message_type(@images) + " user" } } + bold { "> " }
610
+ begin
611
+ if content = handle_tool_call_results?
612
+ @parse_content = false
613
+ else
614
+ content = enable_command_completion do
615
+ if prefill_prompt = @prefill_prompt.full?
616
+ Reline.pre_input_hook = -> {
617
+ Reline.insert_text prefill_prompt.gsub(/\n*\z/, '')
618
+ @prefill_prompt = nil
619
+ }
620
+ else
621
+ Reline.pre_input_hook = nil
622
+ end
623
+ Reline.readline(input_prompt, true)&.chomp
581
624
  end
582
- Reline.readline(input_prompt, true)&.chomp
625
+ end
626
+ rescue Interrupt
627
+ if message = server_socket_message
628
+ type = message.type.full?(:to_sym) || :socket_input
629
+ content = message.content
630
+ @parse_content = message.parse
631
+ STDOUT.puts color(112) { "Received a server socket message. Processing now…" }
632
+ else
633
+ raise
583
634
  end
584
635
  end
585
- rescue Interrupt
586
- if message = server_socket_message
587
- type = message.type.full?(:to_sym) || :socket_input
588
- content = message.content
589
- @parse_content = message.parse
590
- STDOUT.puts color(112) { "Received a server socket message. Processing now…" }
591
- else
592
- raise
593
- end
594
- end
595
636
 
596
- if type == :terminal_input
597
- case next_action = handle_input(content)
598
- when :next
599
- next
600
- when :redo
601
- redo
602
- when :return
603
- return
604
- when String
605
- content = next_action
637
+ if type == :terminal_input
638
+ case next_action = handle_input(content)
639
+ when :next
640
+ next
641
+ when :redo
642
+ redo
643
+ when :return
644
+ return
645
+ when String
646
+ content = next_action
647
+ end
606
648
  end
607
649
  end
608
650
 
@@ -11,25 +11,29 @@ module OllamaChat::Clipboard
11
11
  # its content to the system clipboard using the command specified in
12
12
  # the configuration (config.copy).
13
13
  #
14
- # @param content [Boolean] If true, copies the content of the message;
14
+ # @param content [true, false] If true, copies the content of the message;
15
15
  # if false, copies the entire message object (default: false)
16
16
  #
17
17
  # @raise [OllamaChat::OllamaChatError] if the clipboard command specified
18
18
  # in config.copy is not found in the system's PATH
19
19
  # @raise [OllamaChat::OllamaChatError] if no assistant message is available
20
20
  # to copy to the clipboard
21
- def perform_copy_to_clipboard(content: false)
22
- if message = @messages.find_last(content:) { _1.role == 'assistant' }
21
+ def perform_copy_to_clipboard(text: nil, content: false)
22
+ text ||= last_message_content(content:)
23
+ if text
23
24
  copy = `which #{config.copy}`.chomp
24
25
  if copy.present?
25
26
  IO.popen(copy, 'w') do |clipboard|
26
- clipboard.write(message.content)
27
+ clipboard.write(text)
27
28
  end
29
+ true
28
30
  else
29
- raise OllamaChat::OllamaChatError, "#{config.copy.inspect} command not found in system's path!"
31
+ raise OllamaChat::OllamaChatError,
32
+ "#{config.copy.inspect} command not found in system's path!"
30
33
  end
31
34
  else
32
- raise OllamaChat::OllamaChatError, "No response available to copy to the system clipboard."
35
+ raise OllamaChat::OllamaChatError,
36
+ "No text available to copy to the system clipboard."
33
37
  end
34
38
  end
35
39
 
@@ -67,6 +71,26 @@ module OllamaChat::Clipboard
67
71
 
68
72
  private
69
73
 
74
+ # Returns the content of the last assistant message.
75
+ #
76
+ # This private helper method finds the most recent message from the assistant
77
+ # in the messages array and returns its content. It is used by
78
+ # `perform_copy_to_clipboard` when no custom text is provided.
79
+ #
80
+ # @param content [true, false] If true, returns the content of the message;
81
+ # if false, returns nil if no assistant message is found (default: false)
82
+ #
83
+ # @return [String, nil] The content of the last assistant message, or nil if
84
+ # no assistant message is found
85
+ #
86
+ # @example
87
+ # # Assuming @messages contains assistant messages
88
+ # last_message_content
89
+ # # => "This is the last assistant response"
90
+ def last_message_content(content: false)
91
+ @messages.find_last(content:) { _1.role == 'assistant' }&.content
92
+ end
93
+
70
94
  # Copies the last assistant message to the system clipboard.
71
95
  #
72
96
  # This method is the interface for copying assistant messages to the
@@ -74,8 +98,10 @@ module OllamaChat::Clipboard
74
98
  # handles any OllamaChat::OllamaChatError exceptions by printing the error
75
99
  # message to standard error and does not re-raise the exception.
76
100
  def copy_to_clipboard
101
+
77
102
  perform_copy_to_clipboard
78
103
  STDOUT.puts "The last response has been successfully copied to the system clipboard."
104
+ true
79
105
  rescue OllamaChat::OllamaChatError => e
80
106
  STDERR.puts e.message
81
107
  end
@@ -83,18 +83,30 @@ module OllamaChat::ConfigHandling
83
83
  # 3. If editing was successful, prompts the user to restart
84
84
  # `ollama_chat` if desired.
85
85
  def edit_config
86
- unless editor = OC::EDITOR?
87
- STDERR.puts "Need the environment variable var EDITOR defined to use an editor"
88
- return
89
- end
90
- result = system Shellwords.join([ editor, @ollama_chat_config.filename ])
91
- if result
86
+ if result = edit_file(@ollama_chat_config.filename)
92
87
  if ask?(prompt: "Do you want to restart #{progname}? (y/n) ") =~ /\Ay/i
93
88
  save_conversation(OC::XDG_CACHE_HOME + 'backup.json')
89
+ save_history
94
90
  exec($0, *ARGV)
91
+ else
92
+ STDOUT.puts "Skipped reloading the config."
95
93
  end
96
94
  else
97
95
  STDERR.puts "Editor returned a non-zero status!"
98
96
  end
99
97
  end
98
+
99
+ # Reloads the current configuration by restarting the process.
100
+ #
101
+ # @example Restarting the app after confirmation
102
+ # config.reload_config # => restarts if user answers "y"
103
+ def reload_config
104
+ if ask?(prompt: "Do you want to restart #{progname}? (y/n) ") =~ /\Ay/i
105
+ save_conversation(OC::XDG_CACHE_HOME + 'backup.json')
106
+ save_history
107
+ exec($0, *ARGV)
108
+ else
109
+ STDOUT.puts "Skipped reloading the config."
110
+ end
111
+ end
100
112
  end
@@ -0,0 +1,61 @@
1
+ # Module for editing files using the configured editor
2
+ module OllamaChat::FileEditing
3
+ # Opens a file in the configured editor for editing.
4
+ #
5
+ # @param filename [String, Pathname] Path to the file to edit
6
+ # @return [true, false, nil] Exit status if successful, nil if editor not
7
+ # configured
8
+ def edit_file(filename)
9
+ unless editor = OC::EDITOR?
10
+ STDERR.puts "Need the environment variable var EDITOR defined to use an editor"
11
+ return
12
+ end
13
+ system Shellwords.join([ editor, filename ])
14
+ end
15
+
16
+ # The vim method creates and returns a new Vim instance for interacting with
17
+ # a Vim server.
18
+ #
19
+ # This method initializes a Vim client that can be used to insert text into
20
+ # Vim buffers or open files in a running Vim server. It derives the server
21
+ # name from the provided argument or uses a default server name based on the
22
+ # current working directory.
23
+ #
24
+ # @param server_name [ String, nil ] the name of the Vim server to connect to
25
+ # If nil or empty, a default server name is derived from the current
26
+ # working directory
27
+ #
28
+ # @return [ OllamaChat::Vim ] a new Vim instance configured with the
29
+ # specified server name
30
+ def vim(server_name = nil)
31
+ clientserver = config.vim?&.clientserver
32
+ OllamaChat::Vim.new(server_name, clientserver:)
33
+ end
34
+
35
+ # Inserts provided **text** into Vim using the configured editor client.
36
+ #
37
+ # @param [String, nil] text – Text to insert; if `nil`, defaults to the
38
+ # last response.
39
+ #
40
+ # @param [true, false] content – Treat input as content‑mode (`true`) or
41
+ # plain text (`false`).
42
+ #
43
+ # @return [true, false] true if insertion succeeded; otherwise raises
44
+ # OllamaChat::OllamaChatError.
45
+ #
46
+ # @raise [OllamaChat::OllamaChatError]
47
+ # * Raised when no text is available and insertion cannot proceed.
48
+ # * Also raised if the underlying Vim client reports a failure.
49
+ def perform_insert(text: nil, content: false)
50
+ text ||= last_message_content(content:)
51
+ if text
52
+ unless vim.insert(text)
53
+ raise OllamaChat::OllamaChatError, "Inserting text into editor failed!"
54
+ end
55
+ true
56
+ else
57
+ raise OllamaChat::OllamaChatError,
58
+ "No text available to copy to the system clipboard."
59
+ end
60
+ end
61
+ end