roxma / nvim-completion-manager

:warning: PLEASE USE https://github.com/ncm2/ncm2 INSTEAD
MIT License
917 stars 49 forks source link

make abbreviation more useful. #102

Open 257 opened 7 years ago

257 commented 7 years ago

i'm writing a one that hooks up to google's translation service; early efforts here: https://github.com/257/gtr

google's web interface works with pulling the suggestions for user-entered characters from their completion service and then using a call-back function to translate those suggestions into a target language using their translate service. these translated suggestions in target language are really just hints. the module i have for feeding the suggestions (no hints yet) is here: https://github.com/257/cm_sources/blob/master/trans.py

it would be nice to be able to feed the hints along side the suggestions. first candidate for this seems to be the abbreviation or better yet another column for inserting the hint.

roxma commented 7 years ago

If you feed an array of dict as matches, (:help complete-items), and fill the menu field, you will be able to show the text you want.`

257 commented 7 years ago

so something like this:

[debug] got 8 suggestions
[debug] main
{
  "word":"tu",
  "menu":"you"
}
[debug] main
{
  "word":"toujours",
  "menu":"always"
}
[debug] main
{
  "word":"tu fais quoi dans la vie",
  "menu":"What do you do in life"
}
[debug] main
{
  "word":"trouver",
  "menu":"find"
}
[debug] main
{
  "word":"tout",
  "menu":"all"
}
[debug] main
{
  "word":"toutefois",
  "menu":"however"
}
[debug] main
{
  "word":"tableau",
  "menu":"board"
}
[debug] main
{
  "word":"très",
  "menu":"very"
}

and where am i sending that to nvim-compeletion or to vim directly?

257 commented 7 years ago

please have look at this: https://github.com/257/gtr

to compile and run you would need json-c from their git repo. then you can do: ./json_parser t and it will return:

{
  "word":"tu",
  "menu":"you"
}
{
  "word":"toujours",
  "menu":"always"
}
{
  "word":"trouver",
  "menu":"find"
}
{
  "word":"tableau",
  "menu":"board"
}
{
  "word":"trois",
  "menu":"three"
}
{
  "word":"tout",
  "menu":"all"
}
{
  "word":"très",
  "menu":"very"
}
{
  "word":"tu fais quoi dans la vie",
  "menu":"What do you do in life"
}

i'm still debating how to slice and dice this before feeding it into matches. any suggestions?

roxma commented 7 years ago

Please read :help cm#complete() and :help NCM-source-exameples

257 commented 7 years ago

i already use those here: https://github.com/257/cm_sources/blob/master/trans.py

my question, i think, comes down to, what is acceptable Dictionary format? there is vim dictionary which i think would be like:

{'foo': 0, 'bar': 1}

but if you notice, what my program returns is a json, each match is a json object. i notice that you include json at the beginning of your scripts so i was wondering if cm can understand json if i send it over and what's the proper syntax?

roxma commented 7 years ago

You can output a json array, then you can read the whole output in python and json-decode it.

It should be something like

[{ "word": "Print", "abbr": "foobar"}, ...]

Then do matches = json.loads(result.decode('utf-8')) in python.

257 commented 7 years ago

done! thanks.

FYI! https://github.com/257/cm_sources/blob/master/trans.py https://github.com/257/gtr

257 commented 7 years ago

oh, and if i could include everything from the last '.' (period) in what i send to my google-translate client i would be nice too. i believe one of these need to be changed: https://github.com/257/cm_sources/blob/master/trans.py#L16

word_pattern=r'[\w/]+',
cm_refresh_patterns=[r'\.$'],)
257 commented 6 years ago

i mean something like:

word_pattern=r'[.]\s.*'

but that in particular doesn't work. in fact it includes the closing period '.' from the previous sentence which is not what we want.

257 commented 6 years ago

in a buffer with only this string salut. je compren this regex \.\s\zs.*\.\ze matches je compren which is what i want.

now how do i pass that to cm?

as a side note: in a buffer with salut. je comprends. above regex will include the closing dot (after comprends). \.\s\zs.*\ze\. excludes the closing dot from match.

btw: in logs i see backslashitis for world_pattern, may be cm can use '\v' ?

roxma commented 6 years ago

There's explanation on how patterns are used in this section :help NCM-source-exameples

257 commented 6 years ago

i tried with ctx['typed'], word_pattern and proper PCRE regex for
cm_refresh_patterns=[r'(\.|^)?.*?$\.'] but i can't get cm to send over the complete sentence. say i have a buffer like this

salut. je comp

and cursor is at the end of the line. all i'm getting at my end is comp, i would like to have je comp being sent over.

roxma commented 6 years ago

If you add space into word_pattern, r'[\w\s]+', you will get ' je comp' as ctx['base']

If you want completion to be triggered after . character, simply add r'\.' into cm_refresh_paterns

257 commented 6 years ago

thanks, it's working now. i had to modify my client a bit.

now i have another problem! {context} get outdated. i think it's because of space between je and comp.

in nvim-completion-manager.txt i found a reference to {context} and {refresh} under cm#complete(). any python equivalent for that function?

257 commented 6 years ago

hmm, matches won't pop up the menu even if i type slowly. i.e. context is not outdated and yet matches are ignored.

[INFO @ gtr.py:cm_refresh:78] 26499 - TRANS RESULTS: [b'[\n  {\n    "word":"je",\n    "menu":"I"\n  },\n  {\n    "word":"je t'aime",\n    "menu":"I like you"\n  },\n  {\n    "word":"je suis",\n    "menu":"I am"\n  },\n  {\n    "word":"je vais",\n    "menu":"I go"\n  },\n  {\n    "word":"je m'appelle",\n    "menu":"I\'m calling"\n  },\n  {\n    "word":"je veux",\n    "menu":"I want"\n  },\n  {\n    "word":"je ne sais pas",\n    "menu":"I do not know"\n  },\n  {\n    "word":"je vais bien",\n    "menu":"I\'m fine"\n  }\n]']
[INFO @ gtr.py:cm_refresh:80] 26499 - TRANS matches: [[{'menu': 'I', 'word': 'je'}, {'menu': 'I like you', 'word': 'je t'aime'}, {'menu': 'I am', 'word': 'je suis'}, {'menu': 'I go', 'word': 'je vais'}, {'menu': "I'm calling", 'word': 'je m'appelle'}, {'menu': 'I want', 'word': 'je veux'}, {'menu': 'I do not know', 'word': 'je ne sais pas'}, {'menu': "I'm fine", 'word': 'je vais bien'}]]
[INFO @ cm_core.py:cm_complete:177] 26499 - [gtr] outdated matches, old typed [salut. je ] cur typed[salut. je]
[INFO @ cm_core.py:cm_complete:182] 26499 - [gtr] matches is outdated. ignore them.
[INFO @ cm_core.py:cm_refresh:355] 26499 - not notifying any channels, _refresh_completions now
[INFO @ cm_core.py:_refresh_completions:491] 26499 - _refresh_completions names: [], startcol: 9, matches: []
[INFO @ cm_core.py:_complete:605] 26499 - matches==0, _last_matches==0, ignore
[INFO @ cm_core.py:cm_refresh:355] 26499 - not notifying any channels, _refresh_completions now
[INFO @ cm_core.py:_refresh_completions:491] 26499 - _refresh_completions names: [], startcol: 10, matches: []
[INFO @ cm_core.py:_complete:605] 26499 - matches==0, _last_matches==0, ignore
[INFO @ cm_core.py:cm_refresh:359] 26499 - notify_sources_to_refresh calls cnt [0], channels cnt [1]
[INFO @ gtr.py:cm_refresh:60] 26499 - TRANS refreshing_keyword, base [b' je ']
[INFO @ cm_core.py:_refresh_completions:491] 26499 - _refresh_completions names: [], startcol: 11, matches: []
[INFO @ cm_core.py:_complete:605] 26499 - matches==0, _last_matches==0, ignore
[INFO @ gtr.py:cm_refresh:75] 26499 - TRANS result: [[
  {
    "word":"je",
    "menu":"I"
  },
  {
    "word":"je t'aime",
    "menu":"I like you"
  },
  {
    "word":"je suis",
    "menu":"I am"
  },
  {
    "word":"je vais",
    "menu":"I go"
  },
  {
    "word":"je m'appelle",
    "menu":"I'm calling"
  },
  {
    "word":"je veux",
    "menu":"I want"
  },
  {
    "word":"je ne sais pas",
    "menu":"I do not know"
  },
  {
    "word":"je vais bien",
    "menu":"I'm fine"
  }
]]
[INFO @ gtr.py:cm_refresh:78] 26499 - TRANS RESULTS: [b'[\n  {\n    "word":"je",\n    "menu":"I"\n  },\n  {\n    "word":"je t'aime",\n    "menu":"I like you"\n  },\n  {\n    "word":"je suis",\n    "menu":"I am"\n  },\n  {\n    "word":"je vais",\n    "menu":"I go"\n  },\n  {\n    "word":"je m'appelle",\n    "menu":"I\'m calling"\n  },\n  {\n    "word":"je veux",\n    "menu":"I want"\n  },\n  {\n    "word":"je ne sais pas",\n    "menu":"I do not know"\n  },\n  {\n    "word":"je vais bien",\n    "menu":"I\'m fine"\n  }\n]']
[INFO @ gtr.py:cm_refresh:80] 26499 - TRANS matches: [[{'menu': 'I', 'word': 'je'}, {'menu': 'I like you', 'word': 'je t'aime'}, {'menu': 'I am', 'word': 'je suis'}, {'menu': 'I go', 'word': 'je vais'}, {'menu': "I'm calling", 'word': 'je m'appelle'}, {'menu': 'I want', 'word': 'je veux'}, {'menu': 'I do not know', 'word': 'je ne sais pas'}, {'menu': "I'm fine", 'word': 'je vais bien'}]]
257 commented 6 years ago

i just committed the changes to the python wrapper: https://github.com/257/cm_sources/blob/master/gtr.py as of the last commit, back-and-forth is fine between my client and cm but menu is not popping yet.

roxma commented 6 years ago

[INFO @ cm_core.py:cm_complete:177] 26499 - [gtr] outdated matches, old typed [salut. je ] cur typed[salut. je]

It happens when you delete characters.

The completion is triggered at [salut. je ], then you press <backspace> to [salut. je]. There's no completion triggered in this context.

roxma commented 6 years ago

cm_refresh_patterns=[r'(\.|^)?.*?$\.'])

This is weird

If you want completion to be triggered after ., use cm_refresh_patterns=[r'\.']

257 commented 6 years ago

salut won't be completed then. note the ^ there. regex is weird period. and I'm still confused by how you position the brackets [] for word_pattern vs. cm_refresh_patterns. it seems to me that they use different regex engine.

btw, the info log I posted is irrelevant, as you figured. I will post a more relevant debug log in 12 hours or so.

257 commented 6 years ago

also note je t&#39;aime",. something's off with encoding, I will look into it once this is fixed.

roxma commented 6 years ago

You can find how word_pattern and cm_refresh_patterns are used here: https://github.com/roxma/nvim-completion-manager/blob/cf18fb775ef265c9319d2d4fd8815d84ce345040/pythonx/cm_core.py#L417

257 commented 6 years ago

nvim.log_py2_script nvim.log_py3_cm_core

roxma commented 6 years ago

2017-11-17 10:58:20,553 [INFO @ cm_core.py:cm_complete:177] 1366 - [gtr] outdated matches, old typed [salut. je ] cur typed[salut. je co] 2017-11-17 10:58:20,554 [INFO @ cm_core.py:cm_complete:184] 1366 - [gtr] matches is outdated by keyword further typing. I'm gonna keep it.

Matches will not be ignored in this case

roxma commented 6 years ago

The matches is [{'menu': 'I', 'word': 'je'}, {'menu': 'I like you', 'word': 'je t&#39;aime'}, {'menu': 'I am', 'word': 'je suis'}, {'menu': 'I go', 'word': 'je vais'}, {'menu': "I'm calling", 'word': 'je m&#39;appelle'}, {'menu': 'I want', 'word': 'je veux'}, {'menu': 'I do not know', 'word': 'je ne sais pas'}, {'menu': "I'm fine", 'word': 'je vais bien'}]

None of them is appropriate for your typing salut. je co

roxma commented 6 years ago

By the way, you use startcol=7, which is implying the menu will be virtually displayed like

salut. je co
     |je suis ...|
     |je vais ...|

Due to the sapce. All of them will be filtered out.

You should use startcol=8, or pad the space by yourself.

With startcol=8:

salut. je co
      |je suis ...|
      |je vais ...|

With padding:

salut. je co
     | je suis ...|
     | je vais ...|

But still, due to the behavior of prefix matcher, neither of je suis and je vias matches je co

257 commented 6 years ago

that's the match for je you're looking at and yes they don't match je co. je co gets this mathes:

[
  {
    "word":"je comprends",
    "menu":"I understand"
  },
  {
    "word":"je comprend pas",
    "menu":"I do not understand"
  },
  {
    "word":"je comprend",
    "menu":"I understand"
  },
  {
    "word":"je commence",
    "menu":"I begin"
  },
  {
    "word":"je compte sur toi",
    "menu":"I count on you"
  },
  {
    "word":"je comprends pas",
    "menu":"I do not understand"
  },
  {
    "word":"je compte sur vous",
    "menu":"I count on you"
  },
  {
    "word":"je compte",
    "menu":"I count"
  }
]
roxma commented 6 years ago

Try using cm.complete(..., refresh=True) to disable NCM's word caching.

257 commented 6 years ago

doing self.complete(info, ctx, ctx['col'], matches, True) doesn't work either but changing ctx['startcol'] to ctx['col'] pops something! it is off however:

2017-11-21-101208_3840x1080_scrot

roxma commented 6 years ago

startcol is calculated according to your word_pattern, which includes spaces. The matches you sent to NCM trimed the spaces.

You need to restore the spaces in the matches. Or change startcol to exclude the spaces.