Slide 1

Slide 1 text

How ordinary Vim user contributed to Vim VimConf 2017 daisuzu

Slide 2

Slide 2 text

● Daisuke Suzuki ○ https://github.com/daisuzu ○ id:daisuzu ○ @dice_zu ● Vim activities ○ Create plugins ■ Not really famous ones ○ Writing articles for publishing ■ Software Design (July 2012 and October 2013) ○ Send patches ■ 3 in 2016 and 2017; I became a contributor About me

Slide 3

Slide 3 text

Introduction Don't you think that it is difficult to send patches to Vim? ● Skills ○ That obscure source code written in C is called the Demon World ● Manners ○ English ○ How should I behave at vim_dev? ○ Hey all pull requests in the Vim repository are closed... ● Opportunities ○ What should I contribute? From these things, you may feel a big hurdle, but, all you need is a great passion that you want to be a contributor

Slide 4

Slide 4 text

Agenda 1. Episodes about my contribution ○ v8.0.0102 ○ v8.0.0104 ○ v8.0.0512 2. Useful techniques ○ Debugging ○ Testing ○ How to send a patch

Slide 5

Slide 5 text

My attributes ● My skills ○ Vim experience: About 10 years ○ C: Almost college level ○ English: Thank you, @ujm ● My attitude toward OSS ○ Sending lots pull requests aggressively?: No ○ Like to discuss at many issues?: No ○ When I find something wrong, backing up by operation?: Yes

Slide 6

Slide 6 text

Episode of v8.0.0102

Slide 7

Slide 7 text

Fix can not specify the path to the dictionary file for dictionary completion. 1. Add invalid characters to file name in v8.0.0100, 2. Add flags to check characters to some options in v8.0.0101. What src/option.c 5883 - && vim_strpbrk(*varp, (char_u *)"/\\*?[|<>") != NULL) 5883 + && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL) src/option.c 995 - {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP, 995 + {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NFNAME,

Slide 8

Slide 8 text

Details ● One morning, Vim got an error when startup after build ● Found out the cause was v8.0.0101 from commit logs ○ And it is ridiculous to back up by operation... ● Decided to write a patch ○ Enthusiasm was rising by VimConf 2016 held on the same month ○ Using dictionary completion is minorities, so I thought that I had to fix it myself ○ I taught dictionary completion to my teammates a while ago, and it will be in trouble if it can't be used ○ Maybe it was a careless mistake, but I'd like to add a test code so that it will not reoccur at all E474: Invalid argument: dictionary=/usr/share/dict/words

Slide 9

Slide 9 text

Action ● Created a branch that undo the option with test added in same day ○ I didn't know how to add tests, nay, how to run tests ● Decided to send patch to vim_dev, after wondering where to send ○ There were issues on GitHub, but there was a person reporting it with vim_dev earlier than that ● However, Bram declared the fix in vim_dev, so I sent only the test part ○ It seemed to be fixed without doing anything, but I didn't want to waste the effort so far ● Merged in the next morning patch 8.0.0102 Problem: Cannot set 'dictionary' to a path. Solution: Allow for slash and backslash. Add a test (partly by Daisuke Suzuki, closes #1279, closes #1284)

Slide 10

Slide 10 text

--- a/src/option.c +++ b/src/option.c @@ -458,0 +459 @@ struct vimoption +#define P_NDNAME 0x8000000L /* only normal dir name chars allowed */ @@ -995 +996 @@ static struct vimoption options[] = - {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NFNAME, + {"dictionary", "dict", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME, @@ -5882,2 +5883,4 @@ did_set_string_option( - else if ((options[opt_idx].flags & P_NFNAME) + else if (((options[opt_idx].flags & P_NFNAME) && vim_strpbrk(*varp, (char_u *)"/\\*?[|;&<>\r\n") != NULL) + || ((options[opt_idx].flags & P_NDNAME) + && vim_strpbrk(*varp, (char_u *)"*?[|;&<>\r\n") != NULL)) --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -108,0 +109,15 @@ endfunc + +func Test_dictionary() + " Check that it's possible to set the option. + set dictionary=/usr/share/dict/words + call assert_equal('/usr/share/dict/words', &dictionary) + set dictionary=/usr/share/dict/words,/and/there + call assert_equal('/usr/share/dict/words,/and/there', &dictionary) + set dictionary=/usr/share/dict\ words + call assert_equal('/usr/share/dict words', &dictionary) + + " Check rejecting weird characters. + call assert_fails("set dictionary=/not&there", "E474:") + call assert_fails("set dictionary=/not>there", "E474:") + call assert_fails("set dictionary=/not.*there", "E474:") +endfunc

Slide 11

Slide 11 text

Episode of v8.0.0104

Slide 12

Slide 12 text

What Fix missing of the string check in thesaurus option. ● Similar feature of dictionary option used in thesaurus completion ● It should have the same fix as v8.0.0102, but it was not

Slide 13

Slide 13 text

Details ● I knew the option ● It was not included in v8.0.0101, so I doubted that it was forgotten ● The previous patch only added tests, so I thought it was a chance ○ Add a test (partly by Daisuke Suzuki ... ○ Enthusiasm was not cool down yet

Slide 14

Slide 14 text

Action ● Created a patch the next day of v8.0.0102 ○ The contents are almost the same ○ But, test has been added ● Create a pull request on GitHub ● It was merged in less than an hour patch 8.0.0104 Problem: Value of 'thesaurus' option not checked properly. Solution: Add P_NDNAME flag. (Daisuke Suzuki)

Slide 15

Slide 15 text

--- a/src/option.c +++ b/src/option.c @@ -2663 +2663 @@ static struct vimoption options[] = - {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP, + {"thesaurus", "tsr", P_STRING|P_EXPAND|P_VI_DEF|P_ONECOMMA|P_NODUP|P_NDNAME, --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -109,15 +109,23 @@ endfunc -func Test_dictionary() +func Check_dir_option(name) " Check that it's possible to set the option. - set dictionary=/usr/share/dict/words - call assert_equal('/usr/share/dict/words', &dictionary) - set dictionary=/usr/share/dict/words,/and/there - call assert_equal('/usr/share/dict/words,/and/there', &dictionary) - set dictionary=/usr/share/dict\ words - call assert_equal('/usr/share/dict words', &dictionary) + exe 'set ' . a:name . '=/usr/share/dict/words' + call assert_equal('/usr/share/dict/words', eval('&' . a:name)) + exe 'set ' . a:name . '=/usr/share/dict/words,/and/there' + call assert_equal('/usr/share/dict/words,/and/there', eval('&' . a:name)) + exe 'set ' . a:name . '=/usr/share/dict\ words' + call assert_equal('/usr/share/dict words', eval('&' . a:name)) " Check rejecting weird characters. - call assert_fails("set dictionary=/not&there", "E474:") - call assert_fails("set dictionary=/not>there", "E474:") - call assert_fails("set dictionary=/not.*there", "E474:") + call assert_fails("set " . a:name . "=/not&there", "E474:") + call assert_fails("set " . a:name . "=/not>there", "E474:") + call assert_fails("set " . a:name . "=/not.*there", "E474:") +endfunc + +func Test_dictionary() + call Check_dir_option('dictionary') +endfunc + +func Test_thesaurus() + call Check_dir_option('thesaurus') endfunc

Slide 16

Slide 16 text

Episode of v8.0.0512

Slide 17

Slide 17 text

What Fix the problem that the candidate of insert mode completion might be a long time. ● There was unnecessary waiting when looking for candidates from files and buffers ● That is, as there are more candidates like dictionary completion becomes slow ○ There was also an influence on other completions, but it doesn't matter when not many candidates ○ It occurred only in the CUI version of Linux and Mac, and it did not affect Windows or MacVim

Slide 18

Slide 18 text

Details ● At first I thought that it was due to my PC, ○ The specs were not so good ○ Despite this, heavy background processing was frequently performed ● Colleague said it's became slow, so I found out ○ It was fast when turn back v8.0.0104 to v8.0.0000 ● I planned to make my colleague a contributor, ○ At least, nobody seemed to be in trouble ○ Even if he could not make it to the end, I thought that just only have to report the results so far ○ I had been investigating so that I can give him a hint anytime ● Without progress, decided to change my job and write a patch

Slide 19

Slide 19 text

Action ● Immediately found out the patch and function that caused it ○ It is v8.0.0050, result of git bisect ○ mch_inchar() in os_unix.c was greatly modified ● But I could not find a root cause at all, so trial and error over and over ○ using debugger ● I managed to fix it, but no confidence, so I asked vim-jp for help ○ Thank you, @h_east ○ ● After that, I created a pull request and it was merged on the same day patch 8.0.0512: check for available characters takes too long Problem: Check for available characters takes too long. Solution: Only check did_start_blocking if wtime is negative. (Daisuke Suzuki, closes #1591)

Slide 20

Slide 20 text

--- a/src/os_unix.c +++ b/src/os_unix.c @@ -506,17 +506,17 @@ mch_inchar( if (do_resize /* interrupted by SIGWINCH signal */ #ifdef FEAT_CLIENTSERVER || server_waiting() #endif #ifdef MESSAGE_QUEUE || interrupted #endif || wait_time > 0 - || !did_start_blocking) + || (wtime < 0 && !did_start_blocking)) continue; /* no character available or interrupted */ break; } return 0; }

Slide 21

Slide 21 text

Intermediate Summary ● Bug fix patches are easily approved ○ Recommended for beginner ○ Building Vim everyday is a good habit to find problems ● Vim talk at work is important ○ There is something new discovery ○ It leads to problem solving

Slide 22

Slide 22 text

Useful techniques

Slide 23

Slide 23 text

Debugging (gdb) break os_unix.c:399 (gdb) break os_unix.c:507 (gdb) ignore 1 100000 (gdb) ignore 2 100000 (gdb) continue (gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x000000000052fa50 in mch_inchar at os_unix.c:399 breakpoint already hit 3615 times ignore next 96385 hits 2 breakpoint keep y 0x000000000052fb02 in mch_inchar at os_unix.c:507 breakpoint already hit 20073 times ignore next 79927 hits ● gdb ○ n(next), s(step), l(list), bt(backtrace), b(break) ○ Count the numbers executed with the combination of break and ignore

Slide 24

Slide 24 text

Testing ● make test ○ When adding a test, modify Make_all.mak and write a test with Vim script ○ For details, refer to src/testdir/README.txt in repository

Slide 25

Slide 25 text

How to send a patch ● vim_dev ○ Google Groups(https://groups.google.com/d/forum/vim_dev) ○ A patch can be attached or a link to gist ■ Unified diff format is preferred ○ Posting requires approval of account ● GitHub ○ https://github.com/vim/vim ○ Pull request like other OSS ○ But instead of merging on github, it is merged at Bram's hand and committed to master

Slide 26

Slide 26 text

Conclusion ● Let's do it who want to be a contributor or interested in become contributor! ○ Let's get started from where you can ● (For Japanese) If there is something, feel free to contact vim-jp! ○ It's better than holding alone or just posted to twitter ○ Someone will take a consultation even when there is no confidence in the patch or English