@@ -12,10 +12,10 @@ const REST_TEXT_MARKER: &str = "# --- ignore-rest ---";
1212/// identified by a `filename_safe_intent` to help the user understand what's wanted of them.
1313/// Note that this string must be valid in filenames.
1414///
15- /// Returns the edited text (*without known encoding*), with comment lines (starting with `# `) removed.
16- pub fn from_editor_no_comments ( filename_safe_intent : & str , initial_text : & str ) -> Result < BString > {
17- let content = from_editor ( filename_safe_intent, initial_text, None , ".txt" ) ?;
18- let filtered_lines = filter_content_from_editor ( content. as_bstr ( ) ) ;
15+ /// Returns the edited text (*without known encoding*), with comment lines (starting with `comment_char `) removed.
16+ pub fn from_editor_no_comments ( filename_safe_intent : & str , initial_text : & str , comment_char : char ) -> Result < BString > {
17+ let content = from_editor_impl ( filename_safe_intent, initial_text, None , ".txt" , Some ( comment_char ) ) ?;
18+ let filtered_lines = filter_content_from_editor ( content. as_bstr ( ) , comment_char ) ;
1919 Ok ( filtered_lines. into_iter ( ) . collect ( ) )
2020}
2121
@@ -25,23 +25,26 @@ pub fn from_editor_no_comments(filename_safe_intent: &str, initial_text: &str) -
2525/// If `diff_text` is `Some`, appends it after a `REST_TEXT_MARKER` separator line in the editor.
2626/// The marker and everything below it is automatically stripped from the returned text.
2727///
28- /// Returns the edited text (*without known encoding*), with comment lines (starting with `# `) removed.
28+ /// Returns the edited text (*without known encoding*), with comment lines (starting with `comment_char `) removed.
2929pub fn from_editor_no_comments_as_patch (
3030 filename_safe_intent : & str ,
3131 initial_text : & str ,
3232 diff_text : Option < & str > ,
33+ comment_char : char ,
3334) -> Result < BString > {
34- let content = from_editor ( filename_safe_intent, initial_text, diff_text, ".patch" ) ?;
35- let filtered_lines = filter_content_from_editor ( content. as_bstr ( ) ) ;
35+ let content = from_editor_impl ( filename_safe_intent, initial_text, diff_text, ".patch" , Some ( comment_char ) ) ?;
36+ let filtered_lines = filter_content_from_editor ( content. as_bstr ( ) , comment_char ) ;
3637 Ok ( filtered_lines. into_iter ( ) . collect ( ) )
3738}
3839
39- /// Strip comment lines (starting with '#') and everything below `REST_TEXT_MARKER`.
40- fn filter_content_from_editor ( content : & BStr ) -> Vec < & BStr > {
40+ /// Strip comment lines (starting with `comment_char`) and everything below `REST_TEXT_MARKER`.
41+ fn filter_content_from_editor ( content : & BStr , comment_char : char ) -> Vec < & BStr > {
42+ let comment_prefix = comment_char. to_string ( ) ;
43+ let rest_marker = format ! ( "{comment_char} --- ignore-rest ---" ) ;
4144 content
4245 . lines_with_terminator ( )
43- . take_while ( |line| !line. trim_start ( ) . starts_with_str ( REST_TEXT_MARKER ) )
44- . filter ( |line| !line. trim_start ( ) . starts_with_str ( "#" ) )
46+ . take_while ( |line| !line. trim_start ( ) . starts_with_str ( & rest_marker ) )
47+ . filter ( |line| !line. trim_start ( ) . starts_with_str ( & comment_prefix ) )
4548 . map ( |line| line. as_bstr ( ) )
4649 . collect ( )
4750}
@@ -59,6 +62,16 @@ pub fn from_editor(
5962 initial_text : & str ,
6063 rest_text : Option < & str > ,
6164 file_suffix : & str ,
65+ ) -> Result < BString > {
66+ from_editor_impl ( filename_safe_intent, initial_text, rest_text, file_suffix, None )
67+ }
68+
69+ fn from_editor_impl (
70+ filename_safe_intent : & str ,
71+ initial_text : & str ,
72+ rest_text : Option < & str > ,
73+ file_suffix : & str ,
74+ comment_char : Option < char > ,
6275) -> Result < BString > {
6376 const ALLOWED_SUFFIXES : & [ & str ] = & [ ".txt" , ".md" , ".patch" ] ; // feel free to add more allowed suffixes
6477 if !ALLOWED_SUFFIXES . contains ( & file_suffix) {
@@ -76,8 +89,9 @@ pub fn from_editor(
7689 initial_text,
7790 rest_text,
7891 file_suffix,
92+ comment_char,
7993 ) ,
80- None => from_builtin_editor ( filename_safe_intent, initial_text, rest_text) ,
94+ None => from_builtin_editor ( filename_safe_intent, initial_text, rest_text, comment_char ) ,
8195 }
8296}
8397
@@ -88,6 +102,7 @@ fn from_external_editor(
88102 initial_text : & str ,
89103 rest_text : Option < & str > ,
90104 file_suffix : & str ,
105+ comment_char : Option < char > ,
91106) -> Result < BString > {
92107 // Create a temporary file with the initial text
93108 let mut tempfile = tempfile:: Builder :: new ( )
@@ -101,7 +116,10 @@ fn from_external_editor(
101116 if !initial_text. ends_with ( '\n' ) {
102117 writeln ! ( & mut tempfile) ?;
103118 }
104- writeln ! ( & mut tempfile, "{REST_TEXT_MARKER}" ) ?;
119+ let marker = comment_char
120+ . map ( |c| format ! ( "{c} --- ignore-rest ---" ) )
121+ . unwrap_or_else ( || REST_TEXT_MARKER . to_string ( ) ) ;
122+ writeln ! ( & mut tempfile, "{marker}" ) ?;
105123 writeln ! ( & mut tempfile, "{rest_text}" ) ?;
106124 }
107125
@@ -129,6 +147,7 @@ fn from_builtin_editor(
129147 filename_safe_intent : & str ,
130148 initial_text : & str ,
131149 rest_text : Option < & str > ,
150+ comment_char : Option < char > ,
132151) -> Result < BString > {
133152 // Determine editor mode based on the intent
134153 let mode = if filename_safe_intent. contains ( "commit" ) {
@@ -144,7 +163,10 @@ fn from_builtin_editor(
144163 if !initial_text. ends_with ( '\n' ) {
145164 initial_text. push ( '\n' ) ;
146165 }
147- initial_text. push_str ( REST_TEXT_MARKER ) ;
166+ let marker = comment_char
167+ . map ( |c| format ! ( "{c} --- ignore-rest ---" ) )
168+ . unwrap_or_else ( || REST_TEXT_MARKER . to_string ( ) ) ;
169+ initial_text. push_str ( & marker) ;
148170 initial_text. push ( '\n' ) ;
149171 initial_text. push_str ( rest_text) ;
150172 super :: editor:: run_builtin_editor ( filename_safe_intent, & initial_text, mode) ?
@@ -404,7 +426,42 @@ will
404426be
405427ignored"#
406428 ) ) ;
407- let filtered_content = filter_content_from_editor ( raw_content. as_bstr ( ) ) ;
429+ let filtered_content = filter_content_from_editor ( raw_content. as_bstr ( ) , '#' ) ;
430+
431+ assert_eq ! (
432+ filtered_content,
433+ Vec :: from( [
434+ "commit message\n " ,
435+ "\n " ,
436+ "here is a longer description about the commit\n " ,
437+ "\n " ,
438+ "1. It does the thing\n " ,
439+ "2. It does the other thing\n " ,
440+ "\n " ,
441+ ] )
442+ ) ;
443+ }
444+
445+ #[ test]
446+ fn test_filter_content_from_editor_custom_comment_char ( ) {
447+ let raw_content = BString :: from ( format ! (
448+ r#"commit message
449+
450+ here is a longer description about the commit
451+
452+ 1. It does the thing
453+ 2. It does the other thing
454+
455+ ; this line will be ignored
456+ ; as will this
457+ ; --- ignore-rest ---
458+ all
459+ this
460+ will
461+ be
462+ ignored"#
463+ ) ) ;
464+ let filtered_content = filter_content_from_editor ( raw_content. as_bstr ( ) , ';' ) ;
408465
409466 assert_eq ! (
410467 filtered_content,
0 commit comments