2023-09-04 23:17:23 +00:00
use nom ::branch ::alt ;
2023-09-16 02:31:15 +00:00
use nom ::bytes ::complete ::is_not ;
2023-09-04 23:17:23 +00:00
use nom ::bytes ::complete ::tag_no_case ;
use nom ::character ::complete ::anychar ;
2023-09-16 02:31:15 +00:00
use nom ::character ::complete ::space1 ;
2023-09-04 23:17:23 +00:00
use nom ::combinator ::map ;
use nom ::multi ::many0 ;
use nom ::multi ::many_till ;
2023-09-16 02:31:15 +00:00
use nom ::multi ::separated_list0 ;
2023-09-04 23:17:23 +00:00
use super ::keyword ::filtered_keyword ;
2023-09-06 15:45:35 +00:00
use super ::keyword_todo ::todo_keywords ;
2023-09-04 23:17:23 +00:00
use super ::OrgSource ;
2023-09-16 02:31:15 +00:00
use crate ::context ::HeadlineLevelFilter ;
2023-09-04 23:17:23 +00:00
use crate ::error ::Res ;
use crate ::types ::Keyword ;
2023-09-06 15:00:19 +00:00
use crate ::GlobalSettings ;
2023-09-04 23:17:23 +00:00
2023-09-05 02:15:43 +00:00
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
2023-09-11 17:13:28 +00:00
pub ( crate ) fn scan_for_in_buffer_settings < ' s > (
2023-09-04 23:17:23 +00:00
input : OrgSource < ' s > ,
) -> Res < OrgSource < ' s > , Vec < Keyword < ' s > > > {
// TODO: Optimization idea: since this is slicing the OrgSource at each character, it might be more efficient to do a parser that uses a search function like take_until, and wrap it in a function similar to consumed but returning the input along with the normal output, then pass all of that into a verify that confirms we were at the start of a line using the input we just returned.
let keywords = many0 ( map (
many_till ( anychar , filtered_keyword ( in_buffer_settings_key ) ) ,
| ( _ , kw ) | kw ,
) ) ( input ) ;
keywords
}
#[ cfg_attr(feature = " tracing " , tracing::instrument(ret, level = " debug " )) ]
fn in_buffer_settings_key < ' s > ( input : OrgSource < ' s > ) -> Res < OrgSource < ' s > , OrgSource < ' s > > {
2023-09-05 02:39:24 +00:00
alt ( (
tag_no_case ( " archive " ) ,
tag_no_case ( " category " ) ,
tag_no_case ( " columns " ) ,
tag_no_case ( " filetags " ) ,
tag_no_case ( " link " ) ,
tag_no_case ( " priorities " ) ,
tag_no_case ( " property " ) ,
tag_no_case ( " seq_todo " ) ,
tag_no_case ( " setupfile " ) ,
tag_no_case ( " startup " ) ,
tag_no_case ( " tags " ) ,
tag_no_case ( " todo " ) ,
tag_no_case ( " typ_todo " ) ,
) ) ( input )
2023-09-04 23:17:23 +00:00
}
2023-09-06 15:00:19 +00:00
2023-09-11 17:13:28 +00:00
pub ( crate ) fn apply_in_buffer_settings < ' g , ' s , ' sf > (
2023-09-06 15:00:19 +00:00
keywords : Vec < Keyword < ' sf > > ,
original_settings : & ' g GlobalSettings < ' g , ' s > ,
) -> Result < GlobalSettings < ' g , ' s > , String > {
let mut new_settings = original_settings . clone ( ) ;
2023-09-16 02:31:15 +00:00
// Todo Keywords
2023-09-06 15:00:19 +00:00
for kw in keywords . iter ( ) . filter ( | kw | {
kw . key . eq_ignore_ascii_case ( " todo " )
| | kw . key . eq_ignore_ascii_case ( " seq_todo " )
| | kw . key . eq_ignore_ascii_case ( " typ_todo " )
} ) {
let ( _ , ( in_progress_words , complete_words ) ) =
2023-09-06 15:45:35 +00:00
todo_keywords ( kw . value ) . map_err ( | err | err . to_string ( ) ) ? ;
2023-09-06 15:00:19 +00:00
new_settings
. in_progress_todo_keywords
. extend ( in_progress_words . into_iter ( ) . map ( str ::to_string ) ) ;
new_settings
. complete_todo_keywords
. extend ( complete_words . into_iter ( ) . map ( str ::to_string ) ) ;
}
2023-09-16 02:31:15 +00:00
// Startup settings
for kw in keywords
. iter ( )
. filter ( | kw | kw . key . eq_ignore_ascii_case ( " startup " ) )
{
let ( _remaining , settings ) =
separated_list0 ( space1 ::< & str , nom ::error ::Error < _ > > , is_not ( " \t " ) ) ( kw . value )
. map_err ( | err : nom ::Err < _ > | err . to_string ( ) ) ? ;
if settings . contains ( & " odd " ) {
new_settings . odd_levels_only = HeadlineLevelFilter ::Odd ;
}
2023-09-16 02:44:39 +00:00
if settings . contains ( & " oddeven " ) {
new_settings . odd_levels_only = HeadlineLevelFilter ::OddEven ;
}
2023-09-16 02:31:15 +00:00
}
2023-09-06 15:00:19 +00:00
Ok ( new_settings )
}