Code Monkey home page Code Monkey logo

leetcode.vim's Introduction

leetcode.vim

asciicast

Solve LeetCode problems in Vim!

This Vim plugin is inspired by skygragon/leetcode-cli.

Attention: Recently LeetCode used Google reCAPTCHA to enhance security, prohibiting automatic login through LeetCode API.

The new login procedure needs you to login in your browser first so that leetcode.vim can read the LeetCode session cookie from the browser's cookie storage.

Supported browsers are: Chrome, Firefox. Safari is not supported yet.

The one-time setup:

  1. Install keyring and browser-cookie3:
pip3 install keyring browser-cookie3 --user
  1. Set g:leetcode_browser to 'chrome' or 'firefox'.

Thanks @zhuopro (see #25) for his brilliant idea!

Installation

  1. Vim with +python3 feature is required. Install the pynvim package for Neovim:
pip3 install pynvim --user
  1. Install keyring and browser-cookie3:
pip3 install keyring browser-cookie3 --user
  1. Install the plugin:
Plug 'ianding1/leetcode.vim'

Quick Start

  • :LeetCodeList: browse the problems.
  • :LeetCodeTest: run the code with the default test case.
  • :LeetCodeSubmit: submit the code.
  • :LeetCodeSignIn: manually sign in.

Key mappings

leetcode.vim doesn't bind any key mappings by default. Put the following lines to your .vimrc to set up the key mappings.

nnoremap <leader>ll :LeetCodeList<cr>
nnoremap <leader>lt :LeetCodeTest<cr>
nnoremap <leader>ls :LeetCodeSubmit<cr>
nnoremap <leader>li :LeetCodeSignIn<cr>

Customization

g:leetcode_china

When non-zero, use LeetCode China accounts instead.

Default value is 0.

g:leetcode_solution_filetype

The preferred programming language.

Values: 'cpp', 'java', 'python', 'python3', 'csharp', 'javascript', 'ruby', 'swift', 'golang', 'scala', 'kotlin', 'rust'.

Default value is 'cpp'.

g:leetcode_browser

Set to the browser that stores the LeetCode session cookie.

Values: 'disabled', 'chrome', 'firefox'

Default value is 'disabled'.

g:leetcode_hide_paid_only

Hide the paid only problems on the list.

Default value is 0.

g:leetcode_hide_topics

Hide the topics section.

Default value is 0

g:leetcode_hide_companies

Hide the companies section.

Default value is 0

g:leetcode_problemset

Set the problemset to get from leetcode.

Default value is all

Updates

  • 2019/12/20: Fix the login issue caused by reCAPTCHA.
  • 2019/08/01: Support custom test input
  • 2019/07/28: Support showing frequencies and sorting by columns
  • 2019/07/27:
    • Support LeetCode China accounts
    • Support refreshing
  • 2019/07/23: Support topics and companies

FAQ

I use Ubuntu and get errors when signing in. How can I fix it?

Ubuntu users might see the error message below when signing in.

    raise InitError("Failed to unlock the collection!")
keyring.errors.InitError: Failed to unlock the collection!

It's caused by the misconfiguration of python-keyring. One way to fix it is to create a file ~/.local/share/python_keyring/keyringrc.cfg with the following content:

[backend]
default-keyring=keyring.backends.Gnome.Keyring

Why can't I test the problem/submit the problem/list the problems?

Once you sign in on your browser in LeetCode website, the LeetCode session in Vim get expired immediatelly. Then you need to sign in again in Vim before doing other things. (No longer having this problem)

Why can't I test and submit solutions?

According to issue #5, if the email address is not active, then you can only login and download problems, but cannot test and submit any code.

I got some errors like "ModuleNotFoundError: No module named 'keyring.util.escape'"

This solution worked for me:

pip3 install --upgrade keyrings.alt

leetcode.vim's People

Contributors

axrt avatar devinjeon avatar gu18168 avatar ianding1 avatar korbinzhang avatar ptosi avatar tenfyzhong avatar thomasding avatar zhngjan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

leetcode.vim's Issues

LeetcodeList Error: Eval did not return a valid python object

File "/Users/tiantengfei/.vim/bundle/leetcode.vim/autoload/leetcode.py", line 233, in get_problems
problems.extend(_get_category_problems(c))
File "/Users/tiantengfei/.vim/bundle/leetcode.vim/autoload/leetcode.py", line 220, in _get_category_problems
'ac_rate': p['stat']['total_acs'] / p['stat']['total_submitted'],
ZeroDivisionError: division by zero
E858: Eval did not return a valid python object

[feature request] Open problem description in a separate split

Currently, the problem description along with the template code(based on the programming language configured) opens up in a single split. Due to this, when we run LeetCodeTest, and errors which leetcode api sends back does not match with the buffer line number. This causes trouble in debugging. It would be great if we could open the problem split in a separate split, and the code template in another split. Configuration options, if provided, to configure the split would be an added bonus.

Thanks,

Error in opening problems

Thanks for implementing this good plugin!
I'm using this under Ubuntu 18.04 and Neovim.

I was able to sign-in and see menus ad lists.
However, when I tried to open a problem, an error occurs saying

Error detected while processing function <SNR>137_HandleProblemListCR[51]..<SNR>137_ProblemIdFromNr:
line    6:
E117: Unknown function: trim
E15: Invalid expression: trim(items[1], ' ')
line    7:
E121: Undefined variable: strid
E15: Invalid expression: strid
Error detected while processing function <SNR>137_HandleProblemListCR:
line   53:
E716: Key not present in Dictionary: slug
E15: Invalid expression: problem['slug']

I tried several problems but it happened all the time. I don't think it's a keyring thing.
What am I missing here?

A advice about default value

about some default value, i recommend:

if !exists('g:leetcode_username')
  let g:leetcode_username = executable('git')?system('git config --global user.email'):expand('$HOST')
endif

and about 'g:leetcode_china', perhaps can use :language message or $LANG to determine default value?

it is just an advice. Thanks!

Failed to run test and submit

After LeetCodeSubmit command:

error: 'NoneType' object is not subscriptable

After LeetCodeTest command:

Error detected while processing function leetcode#TestSolution[17]..provider#python3#Call:
line   18:
Error invoking 'python_eval' on channel 4 (python3-script-host):
error caught in request handler 'python_eval ['leetcode.get_problem("1")']':
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/pynvim/plugin/script_host.py", line 165, in python_eval
    return eval(expr, self.module.__dict__)
  File "<string>", line 1, in <module>
  File "/Users/crokobit/.vim/plugged/leetcode.vim/autoload/leetcode.py", line 246, in get_problem
    content = q['translatedContent'] or q['content']
TypeError: 'NoneType' object is not subscriptable

exception when login

Please set a password for your new keyring: error caught in request handler 'python_eval ['keyring.set_password("leetcode.vim", "prozhou", "fakepasswd")']'

When submitting test, got error with empty function

NVIM v0.3.8

reproduce procedure:

  1. open question 1, two sum question.
  2. submitting with blank function
  3. got error below.

or

  1. open question 1, two sum question.
  2. submitting with return [0,1]
  3. got error below.

But it shows no error with the right code.

The error is:

Error detected while processing function <SNR>120_CheckRunCodeTask[19]..<SNR>120_ShowRunResultInPreview[15]..<SNR>120_FormatResult[32]..<SNR>120_FormatSection:

line    4:
E714: List required

Add config entry to specify cookie path

browser_cookie3 fails to retrieve cookie of default profile for Chrome if there are multiple user profiles(on Darwin for me). however, browser_cookie3 does support specifying cookie path explicitly.

may be something like this:

let g:leetcode_browser='chrome'
let g:leetcode_cookie_path='path/to/profile/cookie.db'

or we can infer browser from cookie path, keeping one config entry

let g:leetcode_cookie_path='path/to/profile/cookie.db'

Wrong state

This problem has cropped up recently, when I use LeetcodeTest(see the below image), the preview window show Accepted state, but you can see the actual answer is different from expected answer. The LeetcodeSubmit command can display state correctly.

example

How to check :LeetCodeTest result?

I tried the problem "String to Integer (atoi)" and I wanted to test a dummy code as below.

class Solution:
    def myAtoi(self, str: str) -> int:
        print('xx')
        return 0

LeetCode webpage is supposed to show:

Wrong answer
Your input  "42"
stdout        xx
Output       0
Expected   42

However, What I'm seeing in (neo)vim is just:

# Test Input
"42"

Is this right? What info is the plugin supposed to show? Is my setting wrong?

Chinese comment not decode correct.

MACOS: 10.14.6
VIM:8.1 1-1700
leetcode.vim: up to date.
python: 3.7.4

When I open my submitted code. I get my Chinese comment wrong rendered.It's just like messy code. I have no idea about this. It's there anyone who handled this situation. Pls guide me how to fix it.
image

LeetcodeTest always return Wrong Answer

the answer is :
class Solution {
public:
vector twoSum(vector& nums, int target) {
for(int i = 0; i < nums.size()-1; i++) {
for(int j = i+1; j< nums.size(); j++) {
if(nums[i] + nums[j] == target) {
return {i, j};
}
}
}
return {};
}
};
Screen Shot 2021-04-06 at 9 03 04 AM

but submit can be accepted.
Screen Shot 2021-04-06 at 9 07 49 AM

File name problem

When I use Rust to solve problems, the problem's file name will be a problem. For example, problem one's file name is two-sum.rs, but in rust, we use _ instead of -. So I need to manually modify the file name to two_sum.rs, and if I want to test or submit, I must revise it again...

Issue when issuing LeetCodeSignIn

E319: Sorry, the command is not available in this version: python3 <<EOF
line 9: E492: Not an editor command: import os
line 10: E492: Not an editor command: import vim
line 12: E492: Not an editor command: plugin_dir = vim.eval('s:current_dir')
line 13: E492: Not an editor command: thirdparty_dir = os.path.join(plugin_dir, 'thirdparty')
line 15: E121: Undefined variable: plugin_dir
line 1325: E171: Missing :endif
line 8: E319: Sorry, the command is not available in this version: python3 <<EOF
line 9: E492: Not an editor command: import os
line 10: E492: Not an editor command: import vim
line 12: E492: Not an editor command: plugin_dir = vim.eval('s:current_dir')
line 13: E492: Not an editor command: thirdparty_dir = os.path.join(plugin_dir, 'thirdparty')
line 15: E121: Undefined variable: plugin_dir
line 1325: E171: Missing :endif E117: Unknown function: leetcode#SignIn

New way to overcome new auth way?

image

I stole cookie from firefox, Now It can works.

def getcookiefromchrome(host='.oschina.net',cookiepath='/data/www/cookie'):
    sql="select host,name,value from moz_cookies where host='%s'" % host
    with sqlite3.connect(cookiepath) as conn:
        cu=conn.cursor()
        cookies={name:value for host,name,value in cu.execute(sql).fetchall()}
        return cookies

def signin(username, password):
    global session
    session = requests.Session()
    if 'cn' in LC_BASE:
        cookie = getcookiefromchrome('.leetcode.cn',cookiepath='/data/www/cookie')
        res = session.get(LC_CSRF)
    else:
        cookie = getcookiefromchrome('.leetcode.com',cookiepath='/data/www/cookie')
        res = session.get(LC_LOGIN)

    session.cookies = requests.utils.add_dict_to_cookiejar(session.cookies, cookie)

    if res.status_code != 200:
        _echoerr('cannot open ' + LC_BASE)
        return False

    return True

Add faq for no active account.

I try this plugin, I is very good. But I just can login and browse problem, But can't test and submit. I try figure it out. The result is my email is not active.

LeetCodeSignIn hitting HTTP response 403 error

VIM plugin was working from long time. Starting today 11/26/2019, leetcode plugin is not able to sign-in. Not sure if its due to some changes to leetcode APIs.
I tried changing the password and logging in using the new one. Didn't work.

INFO level logs:
2019-11-26 08:00:38,155 signin request: headers="{'Origin': 'https://leetcode.com', 'Referer': 'https://leetcode.com/accounts/login/'}" login="[email protected]" 2019-11-26 08:00:38,325 signin response: status="403" body=""

Error detected while processing function leetcode#SignIn[1]..<SNR>123_LoadSessionCookie:

I installed every dependency from main page, and added [backend] default-keyring=keyring.backends.Gnome.Keyring to /home/user/.local/share/python_keyring

I have this error:
Error detected while processing /home/user/.vim/plugged/leetcode.vim/autoload/leetcode.vim:
line   27:
Traceback (most recent call last):
  File "<string>", line 18, in <module>
  File "/home/user/.vim/plugged/leetcode.vim/autoload/leetcode.py", line 22, in <module>
    import browser_cookie3
  File "/home/user/.local/lib/python3.7/site-packages/browser_cookie3/__init__.py", line 29, in <module>
    import keyring
  File "/usr/lib/python3/dist-packages/keyring/__init__.py", line 3, in <module>
    from .core import (
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 189, in <module>
    init_backend()
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 97, in init_backend
    or load_config()
  File "/usr/lib/python3/dist-packages/keyring/core.py", line 154, in load_config
    keyring_cfg = os.path.join(platform.config_root(), filename)
  File "/usr/lib/python3/dist-packages/keyring/util/platform_.py", line 58, in _config_root_Linux
    _check_old_config_root()
  File "/usr/lib/python3/dist-packages/keyring/util/platform_.py", line 50, in _check_old_config_root
    raise RuntimeError(msg.format(**locals()))
RuntimeError: Keyring config exists only in the old location /home/user/.local/share/python_keyring/keyringrc.cfg and should be moved to /home/user/.config/python_keyring/keyringrc.cfg to work with this version of keyring.
line   29:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'leetcode' is not defined
E858: Eval did not return a valid python object
Error detected while processing function leetcode#SignIn[1]..<SNR>123_LoadSessionCookie:
line    6:
Traceback (most recent call last):
  File "<string>", line 1, in <module>
NameError: name 'leetcode' is not defined
E858: Eval did not return a valid python object

I'm using debian, vim 8.1.

Focus on the window split

Thanks for creating this!

Would it be possible to make the plugin focus on the window split when we interact with plugin? Right now any action I take, I have to press extra keystrokes to switch to the window split created by your awesome plugin.

Leetcode Signin Problem

While signing in I got the following error:

Error detected while processing function leetcode#SignIn[1]..<SNR>102_LoadSessionCookie[6]..
provider#python3#Call:
line   18:
Error invoking 'python_eval' on channel 3 (python3-script-host):
error caught in request handler 'python_eval ['leetcode.load_session_cookie("firefox")']':
Traceback (most recent call last):
  File "/home/raman/.local/lib/python3.10/site-packages/secretstorage/util.py", line 46, in
send_and_get_reply
    return self._connection.send_and_get_reply(msg, unwrap=True)
  File "/home/raman/.local/lib/python3.10/site-packages/jeepney/io/blocking.py", line 190, i
n send_and_get_reply
    return unwrap_msg(msg_in)
  File "/home/raman/.local/lib/python3.10/site-packages/jeepney/wrappers.py", line 214, in u
nwrap_msg
    raise DBusErrorResponse(msg)
jeepney.wrappers.DBusErrorResponse: [org.freedesktop.DBus.Error.UnknownMethod] ('Object does
 not exist at path “/org/freedesktop/secrets/collection/login”',)

When opening some questions, I got errors or got blank file.

NVIM v0.3.8

When opening questions like 1007, 1010, 1011, 1014, 1018, 1040, 1051, 1052 ... I got error below:

Error detected while processing function <SNR>120_HandleProblemListCR:
line   53:
E716: Key not present in Dictionary: slug
E15: Invalid expression: problem['slug']

Or when opening some question below, it shows a pure blank file.
e.g. 1013, 1031,

Command to restore previous session?

Is there a way save filter preference which are defined in below variables and command which will restore my vim LeetCode session?

b:leetcode_categories   ['algorithms']
b:leetcode_sort_column  level
b:leetcode_sort_order  asc
b:leetcode_buffer_topic  dynamic-programming
b:leetcode_state       All
b:leetcode_buffer_type  topic
b:leetcode_difficulty  All

LeetCodeTest only opens a new window with #Test Input

After running LeetCodeTest on some the first two-sim problem, I expect to have a 'run code' / 'test' submission. But right now I am only able to use this to see the Test Input.

# Test Input
[2,7,11,15]
9

for the two-sums problem

When running LeetCodeSubmit, I get a window with expected output.

Is there a way to work with system browser-cookie3?

OS: Manjaro

browser-cookie3 was installed by yay -S python-browser-cookie3.

The run command pip install keyring browser-cookie3 --user get:

hmank ~ » pip install keyring browser-cookie3 --user
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
Requirement already satisfied: keyring in /usr/lib/python3.8/site-packages (21.2.0)
Requirement already satisfied: browser-cookie3 in /usr/lib/python3.8/site-packages (0.11.0)
Requirement already satisfied: SecretStorage>=3 in /usr/lib/python3.8/site-packages (from keyring) (3.1.2)
Requirement already satisfied: jeepney>=0.4.2 in /usr/lib/python3.8/site-packages (from keyring) (0.4.3)
Requirement already satisfied: cryptography in /usr/lib/python3.8/site-packages (from SecretStorage>=3->keyring) (2.8)
Requirement already satisfied: six>=1.4.1 in /usr/lib/python3.8/site-packages (from cryptography->SecretStorage>=3->keyring) (1.14.0)
Requirement already satisfied: cffi!=1.11.3,>=1.8 in /usr/lib/python3.8/site-packages (from cryptography->SecretStorage>=3->keyring) (1.14.0)
Requirement already satisfied: pycparser in /usr/lib/python3.8/site-packages (from cffi!=1.11.3,>=1.8->cryptography->SecretStorage>=3->keyring) (2.20)

When run command LeetCodeList in Vim got:

image

Add options to hide the `company` section and paid only problems.

The company section is to long, and I don't need them if I don't subscribe the problems. I think is a good idea to provide an option the hide this section. The same problem with paid only problems. I don't need to see them in the problem list.

I can do this if you agree.

Top Interview Questions Problemset Work Around

I wanted to set my pset to 'top-interview-questions.' This was a little troublesome, so I wanted to show how to do it if anyone is ever curious. Also, I wanted to throw some suggestions out.

I had to inspect the endpoint requests in my browser because g:leetcode_problemset='top-interview-questions' was not working. It turns out that the endpoint is actually 'g:leetcode_problemset=favorite_lists/top-interview-questions'

It would be really helpful if the README and docs had a list of available options.

This alone didn't work, though, because of how the problem object is created. For some reason, the favorite_lists/top-interview-questions endpoint does not contain a reference to 'category.'

For a cheap workaround, I had to go into autoload/leetcode.py and comment out line 223:

#'category': content['category_slug'],

It would be helpful if we can add that key only for psets where we know it is necessary.

Invalid vimscript expression: single-argument printf

After signing in and running :LeetCodeList:

Error detected while processing function leetcode#ListProblems:
E119: Not enough arguments for function: printf
E15: Invalid expression: printf('leetcode.get_problems(["all"])')

and, from :help printf:

printf({fmt}, {expr1} ...)				*printf()*
		Return a String with {fmt}, where "%" items are replaced by
		the formatted form of their respective arguments.

so that {expr1} seems to be required.

This is isolated and shown when running :echo printf("x"):

E119: Not enough arguments for function: printf
E15: Invalid expression: printf("x")

vim --version (Ubuntu 18.04.3 LTS):

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Jun 06 2019 17:31:41)
Included patches: 1-1453
Modified by [email protected]
Compiled by [email protected]
Huge version with GTK2 GUI.

'browser_cookie3 not installed' error occurred although i have installed it already

I have installed the dependency:
$ pip3 install keyring browser-cookie3 --user
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Requirement already satisfied: keyring in ./Library/Python/3.7/lib/python/site-packages (21.2.0)
Requirement already satisfied: browser-cookie3 in /usr/local/lib/python3.7/site-packages (0.11.1)
Requirement already satisfied: importlib-metadata; python_version < "3.8" in /usr/local/lib/python3.7/site-packages (from keyring) (1.5.0)
Requirement already satisfied: pycryptodome in /usr/local/lib/python3.7/site-packages (from browser-cookie3) (3.9.4)
Requirement already satisfied: pyaes in ./Library/Python/3.7/lib/python/site-packages (from browser-cookie3) (1.6.1)
Requirement already satisfied: lz4 in ./Library/Python/3.7/lib/python/site-packages (from browser-cookie3) (3.0.2)
Requirement already satisfied: pbkdf2 in ./Library/Python/3.7/lib/python/site-packages (from browser-cookie3) (1.3)
Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.7/site-packages (from importlib-metadata; python_version < "3.8"->keyring) (3.0.0)

but:
image

my vim version:
VIM - Vi IMproved 8.2 (2019 Dec 12, compiled Apr 29 2020 01:33:43)
macOS version

Error invoking LeetCodeList

Error detected while processing function leetcode#ListProblems:
line   30:
E121: Undefined variable: s:topics_and_companies
E15: Invalid expression: s:topics_and_companies['topics']

Change input for LeetCodeTest

Hello!

Thanks for awesome plugin. It looks interesting.
I didn't find, is it possible to change input for LeetCodeTest command? It would be nice to change input for testing before submitting the solution.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.