Last active
March 11, 2019 08:59
-
-
Save sim590/08aa6f8df00f0784f36af96feaa80828 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" Désactive les replis des sections par le plugin vim-markdown | |
set nofoldenable | |
let g:vim_markdown_folding_disabled = 1 | |
""""""""""""""""""""""""""""""" | |
" Variables de localisation " | |
""""""""""""""""""""""""""""""" | |
" NOTE: Configurer les variables ci-après | |
" NOTE: Le fichier gabarit peut être téléchargé à l'adresse suivante: | |
" https://gist.github.com/293f9c32667bfe12a61046dd6664db8c | |
" Le chemin vers le fichier d'évaluation | |
let s:base_marking_file_path = "/home/simon/Documents/personnel/education/UQAM/maitrise_info/2019/emploi/INF1070/correction/tp1/évaluation.md" | |
" NOTE: Configurer | |
let s:CLASS_GROUP_NUMBER = 12 | |
" NOTE: Configurer | |
let s:TEACHER_NAME = "Moussa Abdenbi" | |
"""""""""""""""""""""""""""""""" | |
" Configuration de UltiSnips " | |
"""""""""""""""""""""""""""""""" | |
" NOTE: Ignorer si le plugin n'est pas installé | |
let g:UltiSnipsSnippetsDir = "/home/simon/Documents/personnel/education/UQAM/maitrise_info/2019/emploi/INF1070/correction/tp1/Ultisnips" | |
let g:UltiSnipsSnippetDirectories += [g:UltiSnipsSnippetsDir] | |
"""""""""""""""""""""""""""""""""""""" | |
" Expressions régulières courantes " | |
"""""""""""""""""""""""""""""""""""""" | |
let s:GROUP_RE = '\(^-\s*Groupe\s*:\)\s*\(.*\)' | |
let s:MISSION_NONUM_RE = '^##\s*\(Solution\s\+de\s\+la\s\+\)\?[mM]ission' | |
let s:MISSION_RE = s:MISSION_NONUM_RE.'\s\+\([0-9]\+\)' | |
let s:MARK_RE = '\(^\*\*Note\*\*\s*:\s*\)\(-\?\s*[0-9]\+\|X\+\)/\([0-9]\+\)' | |
let s:PENALITY_RE = '\(\*\*\s*Pénalité\s*\*\*\s*:\)\s*\([0-9]\+\)\s*pts' | |
let s:COMMENT_RE = '^###\s*Commentaires' | |
let s:NOTHING_TO_NOTICE = '^Rien à signaler.$' | |
let s:NOTHING_DONE = "Rien de fait." | |
fun! s:get_marking_file_path() | |
let l:path = expand('%') | |
let l:mdfile_re = '\(.*\)\.md$' | |
if matchstr(l:path, l:mdfile_re) == "" | return "" | endif | |
let l:m = matchlist(l:path, l:mdfile_re) | |
return match(l:m[1], '_ÉVALUATION$') == -1 ? l:m[1]."_ÉVALUATION.md" : l:path | |
endf | |
fun! s:create_marking_file(path) | |
call system("cp '".s:base_marking_file_path."' '".a:path."'") | |
endf | |
fun! s:init_marking_file() | |
" Assurer qu'on se trouve dans le répertoire du fichier (au cas où 'autochdir' n'est pas | |
" configuré). | |
let l:mf = s:get_marking_file_path() | |
if l:mf == "" | |
echoerr "Ce fichier n'est pas un fichier Markdown." | |
return | |
endif | |
if filereadable(l:mf) == v:false | |
call s:create_marking_file(l:mf) | |
call s:apply_identification(l:mf) | |
endif | |
endf | |
fun! s:go_to_bufwin(expr) | |
let l:wid = getbufinfo(a:expr) | |
let l:lb = bufnr('%') | |
if l:wid != [] && l:wid[0]['windows'] != [] | |
call win_gotoid(l:wid[0]['windows'][0]) | |
return l:lb | |
endif | |
if match(a:expr, '^[0-9]\+$') == -1 | |
exec "silent argadd ".fnameescape(a:expr) | |
endif | |
exec 'silent buffer! '.a:expr | |
return l:lb | |
endf | |
fun! s:apply_identification(path) | |
let l:cp = getcurpos() | |
call cursor(1,1) | |
if search(s:GROUP_RE, 'W') != v:false | |
" Copie du bloc d'identification dans le registre i | |
silent normal vip"iy | |
let l:b = s:go_to_bufwin(a:path) | |
call cursor(1,1) | |
if search(s:GROUP_RE, 'W') != v:false | |
" Remplacement du bloc d'identifcation par le registre i | |
silent normal vip"ip | |
let [l:il, l:_] = searchpos('## Identification', 'nb') | |
let [l:pl, l:_] = searchpos('## Présentation globale', 'n') | |
let l:subs = { | |
\ '[`<>]' : '', | |
\ 'numéro du groupe' : s:CLASS_GROUP_NUMBER, | |
\ 'nom de votre enseignant' : s:TEACHER_NAME | |
\ } | |
for [l:from,l:to] in items(l:subs) | |
execute 'silent! '.l:il.','.l:pl.'substitute/'.l:from.'/'.l:to.'/g' | |
unlet l:from l:to | |
endfor | |
endif | |
silent write | |
call s:go_to_bufwin(l:b) | |
endif | |
call setpos('.', l:cp) | |
endf | |
fun! s:get_cur_mission() | |
let l:cp = getcurpos() | |
let l:mn = 0 | |
if search(s:MISSION_RE, 'bW') != v:false | |
let l:mn = matchlist(getline('.'), s:MISSION_RE)[2] | |
endif | |
call setpos('.', l:cp) | |
if l:mn < 2 || l:mn > 19 | |
echoerr "Les seules missions notées sont les missions 2 à 19" | |
return -1 | |
else | |
return l:mn | |
endif | |
endf | |
fun! s:notice_nothing_done() | |
call s:init_marking_file() | |
let l:mf = s:get_marking_file_path() | |
let l:mn = s:get_cur_mission() | |
if l:mn == -1 | return | endif | |
let l:cp = getcurpos() | |
let l:b = s:go_to_bufwin(l:mf) | |
if search(s:MISSION_NONUM_RE.' '.l:mn, 'w') == v:false || search(s:COMMENT_RE, 'w') == v:false | |
return | |
endif | |
let l:cline = getcurpos()[1] | |
let l:endp = line('$') | |
if search(s:MISSION_NONUM_RE.' '.(l:mn+1), 'w') != v:false | |
let l:endp = getcurpos()[1] | |
endif | |
let l:already_commented = v:false | |
try | |
execute 'silent '.l:cline.','.l:endp.'substitute/'.s:NOTHING_TO_NOTICE.'/'.s:NOTHING_DONE.'/g' | |
silent write | |
catch /E486/ | |
" La substitution a échouché. | |
let l:already_commented = v:true | |
echoerr "La mission est déjà commentée." | |
finally | |
call s:go_to_bufwin(l:b) | |
call setpos('.', l:cp) | |
normal zz | |
endtry | |
if l:already_commented == v:false | |
echo "Mission ".l:mn." noté comme non-complétée." | |
endif | |
endf | |
fun! s:attribute_mark(mark) | |
call s:init_marking_file() | |
let l:mf = s:get_marking_file_path() | |
let l:mn = s:get_cur_mission() | |
if l:mn == -1 | return | endif | |
let l:cp = getcurpos() | |
" TODO: Penser à utiliser un wrapper pour ces bouts de code répétitifs... | |
" Voir: https://vi.stackexchange.com/questions/3920/is-it-possible-to-use-a-delegate-or-to-pass-a-function-as-argument-in-vimscript | |
let l:b = s:go_to_bufwin(l:mf) | |
if search(s:MISSION_NONUM_RE.' '.l:mn, 'w') != v:false && search(s:MARK_RE) != v:false | |
let l:m = matchlist(getline('.'), s:MARK_RE) | |
if l:m[3] < a:mark | |
echoerr "La note attribué ".l:mn." est plus élevée que le total (".l:m[3].")" | |
call s:go_to_bufwin(l:b) | |
call setpos('.', l:cp) | |
return | |
endif | |
call setline(line('.'), l:m[1].a:mark.'/'.l:m[3]) | |
silent write | |
echo "Mission ".l:mn." noté: ".a:mark."/".l:m[3] | |
endif | |
call s:go_to_bufwin(l:b) | |
call setpos('.', l:cp) | |
normal zz | |
endf | |
fun! s:go_to_comment_section() | |
call s:init_marking_file() | |
let l:mf = s:get_marking_file_path() | |
let l:mn = s:get_cur_mission() | |
if l:mn == -1 | return | endif | |
call s:go_to_bufwin(l:mf) | |
call search(s:MISSION_NONUM_RE.' '.l:mn) | |
call search(s:COMMENT_RE) | |
" Le commentaire est deux lignes plus bas. | |
normal 2jzz | |
endf | |
fun s:mark_total() | |
let l:total = system('paste -sd+ <(grep -oP "\*\*Note\*\*:\s+\K[0-9]{1,3}" "'.expand('%').'") | bc') | |
let l:cp = getcurpos() | |
call cursor(1,1) | |
if search(s:PENALITY_RE, 'W') != v:false | |
let l:total -= matchlist(getline('.'), s:PENALITY_RE)[2] | |
endif | |
let l:total_re = substitute(s:MARK_RE, 'Note', 'Note totale', "") | |
if search(l:total_re) != v:false | |
let l:m = matchlist(getline('.'), l:total_re) | |
call setline(line('.'), l:m[1].l:total.'/'.l:m[3]) | |
endif | |
noautocmd write | |
call setpos('.', l:cp) | |
endf | |
fun! s:go_to_presentation_evaluation_section() | |
call s:init_marking_file() | |
let l:mf = s:get_marking_file_path() | |
call s:go_to_bufwin(l:mf) | |
call search('^##\s*Présentation\s*globale') | |
call search(s:COMMENT_RE) | |
normal 2jzz | |
endf | |
fun s:next_mission(re, flags, c) | |
let l:max = a:c == 0 ? 1 : a:c | |
let l:i = 0 | |
let l:beginpos = getcurpos() | |
while l:i < l:max | |
if search(a:re, a:flags) == v:false | |
return | |
endif | |
let l:i += 1 | |
endw | |
let l:cursorp = getcurpos() | |
let l:endlnum = line('$') | |
if search(a:re, a:flags) != v:false | |
let l:endlnum = getcurpos()[1] | |
elseif a:flags =~ 'b' | |
call setpos('.', l:beginpos) | |
return | |
endif | |
let l:cursorp[1] += (l:endlnum-l:cursorp[1])/2 | |
call setpos('.', l:cursorp) | |
normal zz | |
endf | |
""""""""""""""""""""""""""""" | |
" Association des touches " | |
""""""""""""""""""""""""""""" | |
nnoremap <leader>gm :<C-U>call <SID>attribute_mark(v:count)<CR> | |
nmap gm <leader>gm | |
nnoremap <leader>nd :<C-U>call <SID>notice_nothing_done()<CR> | |
nnoremap <leader>gc :call <SID>go_to_comment_section()<CR> | |
nmap gC <leader>gc | |
nnoremap <leader>gp :call <SID>go_to_presentation_evaluation_section()<CR> | |
nmap gp <leader>gp | |
execute "nnoremap <silent> [[ :<C-U>call <SID>next_mission('".s:MISSION_RE."', 'bW', v:count)<CR>" | |
execute "nnoremap <silent> ]] :<C-U>call <SID>next_mission('".s:MISSION_RE."', 'W', v:count)<CR>" | |
" calcul du total après chaque modification | |
au! BufWritePost *_ÉVALUATION.md call <SID>mark_total() | |
au! BufEnter *_solutions-tp1.md set readonly | |
if expand('%') =~ '.*_solutions-tp1.md$' | |
set readonly | |
endif | |
" vim: set sts=2 ts=2 sw=2 tw=100 et : | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment