Skip to content
This repository has been archived by the owner on Aug 30, 2020. It is now read-only.

Implement 'Guess Include Path' feature in 'template.py' #113

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

jhxie
Copy link

@jhxie jhxie commented Dec 1, 2017

In case anyone is still actively monitoring the pull requests:
I have cleaned up the 'template.py' file thoroughly in accordance to the "PEP 8" standard and add two extra configuration options to assist code completion:

  1. Guess Include Path
    Most of the open source projects hosted on "GitHub" that are primarily written in "C/C++" languages involves the extensive use of local headers; but very often the definitions exposed by headers are not visible in the source files (not able to use "YcmCompleter GoToInclude" for example) without first adding include paths to relevant build system configuration files.
    This feature is implemented with simple and straightforward heuristics in order to mitigate this issue: it tries to locate any child sub-directory named either "src", "source", "lib", or the name of the parent directory in sequential order, then recursively walk the determined source tree in a depth first manner in order to get potential include paths (certain paths can be filtered out by specifying file extensions, but default setup would suffice in most situations); similarly, it will also walk the directory of either "include" or "includes", but this time any sub-directories of either is included without take file extension into consideration; lastly it dynamically inject the candidate paths found in previous step to the "flags" variable (prefixing them with "-I").
    Experiment has been made on the stock version of "systemd" and "EASTL" (both projects do not include any sensible default ".ycm_extra_conf.py" file) projects, and the "YcmCompleter GoToInclude" feature work as expected without first building the two projects beforehand (thus without the presence of "compile_commands.json").

  2. Guess Build Path
    Analogous to the previous one mentioned, this feature checks the existence of "build" directory and set up "compilation_database_folder" variable correspondingly.
    This feature is largely experimental and I may choose to drop it in the future should there is no demand for doing so (because the build directory could vary significantly as it is mainly a policy on users' side rather than authors').

- Add 'docstring' to all functions in 'template.py'

- Implement new functions 'GuessBuildDirectory' 'GuessIncludeDirectory',
  'GuessSourceDirectory', and 'TraverseByDepth' in 'template.py'

- Make all the code in 'template.py' PEP 8 conformant
- Add 'source' to the candidate list of 'GuessSourceDirectory'
  function of 'template.py'
template.py Outdated

# ========================== Configuration Options ============================
GUESS_BUILD_DIRECTORY = False # Experimental
GUESS_INCLUDE_PATH = True
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments explaining exactly what these do.

template.py Outdated

# =========================== Constant Definitions ============================
SOURCE_EXTENSIONS = ('.C', '.cpp', '.cxx', '.cc', '.c', '.m', '.mm')
HEADER_EXTENSIONS = ('.H', '.h', '.hxx', '.hpp', '.hh')
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would make more sense to just store these in lower case and use case-insensitive comparison

@rdnetto
Copy link
Owner

rdnetto commented Dec 3, 2017

Apart from a few nits, looks good to me.

- Add extra in-source documentation for 'GUESS_BUILD_DIRECTORY' and
  'GUESS_INCLUDE_PATH'

- Modify 'TraverseByDepth' function to behave in a case-insensitive
  manner
@jhxie
Copy link
Author

jhxie commented Dec 3, 2017

I have made the suggested modification as you described; let me know if you spot any other defect.
Thank you.

basename = os.path.splitext(filename)[0]
for extension in SOURCE_EXTENSIONS:
replacement_file = basename + extension
if os.path.exists(replacement_file):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one corner case that is tricky to handle after I made both SOURCE_EXTENSIONS and HEADER_EXTENSIONS case-insensitive: what if there are two files named "source.c", and "source.C"? I think it is very likely as the file systems most commonly used these days are case-sensitive (for example, ext4, NTFS).

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants