diff --git a/ai-code-file.el b/ai-code-file.el index 60dc37c7..d8e061d8 100644 --- a/ai-code-file.el +++ b/ai-code-file.el @@ -36,6 +36,14 @@ :type 'string :group 'ai-code) +(defcustom ai-code-region-text-max-lines 5 + "Maximum number of region lines whose text is kept in context references. +When the selected region spans more lines than this, context actions +such as `ai-code-copy-buffer-file-name-to-clipboard' copy only the file +path with the line range, without the region text." + :type 'integer + :group 'ai-code) + ;; Variables that will be defined in ai-code.el (defvar ai-code-use-prompt-suffix) (defvar ai-code-prompt-suffix) @@ -101,7 +109,8 @@ If in a Dired buffer, copy the marked files and directories, one path per line, falling back to the file at point or the directory path. In a regular file buffer, append the selected region's line range or the current function name to the file path. Preserve selected text -before that context reference. +before that context reference, unless the region spans more than 5 +lines; then only the file path with line range is copied. With prefix argument ARG \[universal-argument], always return full path instead of processed path. File paths are processed to relative paths with @ prefix if within git repo." @@ -119,7 +128,9 @@ with @ prefix if within git repo." ((buffer-file-name) (let ((context-reference (ai-code--current-file-context-reference arg))) - (if (use-region-p) + (if (and (use-region-p) + (<= (count-lines (region-beginning) (region-end)) + ai-code-region-text-max-lines)) (format "%s in %s" (buffer-substring-no-properties (region-beginning) diff --git a/test/test_ai-code-file.el b/test/test_ai-code-file.el index d55e5572..48c5f07f 100644 --- a/test/test_ai-code-file.el +++ b/test/test_ai-code-file.el @@ -768,6 +768,61 @@ everything is cleaned up afterward." (should (equal (current-kill 0 t) "third in /tmp/sample.el#L3-L3"))))) +(ert-deftest ai-code-test-copy-file-context-short-region-includes-text () + "A region of 5 lines or fewer should keep including the selected text." + (with-temp-buffer + (insert "l1\nl2\nl3\nl4\nl5\n") + (setq buffer-file-name "/tmp/sample.el" + transient-mark-mode t) + (goto-char (point-min)) + (set-mark (point)) + (forward-line 4) + (end-of-line) + (activate-mark) + (let ((kill-ring nil)) + (ai-code-copy-buffer-file-name-to-clipboard t) + (should (equal (current-kill 0 t) + "l1\nl2\nl3\nl4\nl5 in /tmp/sample.el#L1-L5"))))) + +(ert-deftest ai-code-test-copy-file-context-long-region-uses-line-range-only () + "A region longer than 5 lines should copy only the file line range." + (with-temp-buffer + (insert "l1\nl2\nl3\nl4\nl5\nl6\n") + (setq buffer-file-name "/tmp/sample.el" + transient-mark-mode t) + (goto-char (point-min)) + (set-mark (point)) + (forward-line 5) + (end-of-line) + (activate-mark) + (let ((kill-ring nil)) + (ai-code-copy-buffer-file-name-to-clipboard t) + (should (equal (current-kill 0 t) + "/tmp/sample.el#L1-L6"))))) + +(ert-deftest ai-code-test-context-action-long-region-copies-line-range-only () + "C-c a @ copy actions should omit text for regions longer than 5 lines." + (with-temp-buffer + (insert "l1\nl2\nl3\nl4\nl5\nl6\nl7\n") + (setq buffer-file-name "/tmp/sample.el" + transient-mark-mode t) + (goto-char (point-min)) + (set-mark (point)) + (forward-line 6) + (end-of-line) + (activate-mark) + (let ((kill-ring nil) + (selected-actions '("Copy context" + "Copy context with full path"))) + (cl-letf (((symbol-function 'completing-read) + (lambda (&rest _args) (pop selected-actions))) + ((symbol-function 'ai-code--git-root) + (lambda (&optional _dir) nil))) + (ai-code-context-action nil) + (should (equal (current-kill 0 t) "/tmp/sample.el#L1-L7")) + (ai-code-context-action nil) + (should (equal (current-kill 0 t) "/tmp/sample.el#L1-L7")))))) + (ert-deftest ai-code-test-context-action-copies-scoped-context () "Test that context actions copy function and region references." (let* ((repo-root (make-temp-file "ai-code-context-copy-" t))